I am trying to read a text file separated by semicolons such as
3;7;9;
4;7;23;
However, every time I call
while ((c = getc(fp))!= EOF)
putchar(c);
it skips the first value (3) and only outputs:
;7;9;
4;7;23;
Is there any way to get the first value?
Thank you
using C Program.*/
include
int main(){
//file nane
const char *fileName="sample.txt";
//file pointer
FILE *fp;
//to store read character
char ch;
//open file in read mode
fp=fopen(fileName,"r");
if(fp==NULL){
printf("Error in opening file.\n");
return -1;
}
printf("Content of file\n");
while((ch=getc(fp))!=EOF){
printf("%c",ch);
}
fclose(fp);
return 0;
}
Related
C Lang Newb: My goal: Using a character stream using getchar() into an array and write array to a binary file, and then retrieve binary file into array and output string on console. I was successful with all parts except the output to console.
Call to function:
if (c == '6')
loadDoc();
Write file function:
int saveDoc(char document[MAXSIZE], int size){
FILE *f;
f = fopen("document.bin", "wb");
if (!f) {
printf("Error during writing to file !\n");
}
else{
fwrite(&document, sizeof(document), size, f);
fclose(f);
}
return 0;
}
Read file function:
char loadDoc(){
char buffer[1000];
FILE *f;
f = fopen("document.bin", "rb");
if (!f) {
printf("Error during reading file !\n");
}
else {
printf("Size of buffer: %d\n", sizeof(buffer));
fread(&buffer, sizeof(buffer), 1, f);
printf("File cpntents: \n %s\n", buffer);
fclose(f);
}
return 0;
}
Output:
********************
1) Start New Document:
2) View Document:
3) Edit Document:
4) Delete Document:
5) Save Document:
6) Load Document:
7) Exit
********************
6
Size of buffer: 1000
File cpntents:
#p#
When I open file in notebook, actual content of file is:
#p# & P ÿÿÿÿ& ðýb µ# ú ~ù 3 ÿÿÿÿÿÿÿÿ1 þb B# 3 è# 3 =A
The input entered into file saved and expected output to console with file is read:
This code isn't working as expected.
Here is the correct working solution in GCC:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void save_to_binary_file(const char* file_name, const char* text_data)
{
FILE* file = fopen(file_name, "wb");
if(file == NULL)
printf("Failed to open file %s\n", file_name);
if(fwrite(text_data, sizeof(char), strlen(text_data) + 1, file) != (strlen(text_data) + 1))
puts("Failed to write all text data\n");
fclose(file);
}
char* load_binary_file_as_text(const char* file_name)
{
FILE* file = fopen(file_name, "rb");
if(file == NULL)
printf("Failed to open file %s\n", file_name);
fseek(file, 0, SEEK_END);
size_t file_size_in_bytes = ftell(file);
fseek(file, 0, SEEK_SET);
char* read_buffer = (char*)malloc(file_size_in_bytes);
if(fread(read_buffer, 1, file_size_in_bytes, file) != file_size_in_bytes)
puts("Failed to read all the bytes\n");
fclose(file);
return read_buffer;
}
int main()
{
save_to_binary_file("Data.data", "ABCD");
char* buffer = load_binary_file_as_text("Data.data");
printf("%s\n", buffer);
free(buffer);
return 0;
}
The problem was the '&' in the fwrite() call. Removed it and works as expected.
So when I use this 'save' function, it seems to change the data within my structure, to random numbers and icons. If i don't save the file then the integrity of the data within the structure keeps true to the original input.
I'm not sure where the error could be or how to even start to fixing this, thanks for any help.
here is my structure;
struct packet{ // declare structure for packet creation
int source;
int destination;
int type;
int port;
char data[51];
};
here is the function;
//Save the records to a file: follows the same principle as list but uses a file handle (pointer to a file)
//and fprintf to write to the file
void save(int rCount, struct packet *records){
FILE *recordFile; //file handle
char fileName[30] = { '\0'}; //string to store the file name
int i;
puts("Enter a filename to save the records :"); //ask the user for the filename
scanf("%s", fileName); //store the filename: data input should be checked
//here in your program
//try and open the file for writing and react accordingly if there is a problem
if((recordFile = fopen(fileName,"w"))==NULL){
printf("Couldn't open the file: %s\n",fileName);
exit(1);
}
else{ //the file opened so print the records array of packet to it
for(i=0;i<rCount;i++){
fprintf(recordFile,"%04d:%04d:%04d:%04d:%s\n",records[i].source,
records[i].destination,
records[i].type,
records[i].port,
records[i].data);
}
fclose(recordFile); //close the file
}
}
How do you know the structure data is corrupted? Based on your code, I can see your output to file will be wrong based on this line:
fprintf(recordFile,"%04d:%04d:%04d:%04d:%s\n",&records[i].source,
&records[i].destination,
&records[i].type,
&records[i].port,
&records[i].data);
Your pointer referencing is off. Assuming the rest of your program is correct, simply remove the leading &s and I'm guessing this solves most if not all of your problem:
fprintf(recordFile,"%04d:%04d:%04d:%04d:%s\n",records[i].source,
records[i].destination,
records[i].type,
records[i].port,
records[i].data);
Setting: I'm using Lua from a C/C++ environment.
I have several lua files on disk. Those are read into memory and some more memory-only lua files become available during runtime. Think e.g. of an editor, with additional unsaved lua files.
So, I have a list<identifier, lua_file_content> in memory. Some of these files have require statements in them. When I try to load all these files to a lua instance (currently via lua_dostring) I get attempt to call global require (a nil value).
Is there a possibility to provide a require function, which replaces the old one and just uses the provided in memory files (those files are on the C side)?
Is there another way of allowing require in these files without having the required files on disk?
An example would be to load the lua stdlib from memory only without altering it. (This is actually my test case.)
Instead of replacing require, why not add a function to package.loaders? The code is nearly the same.
int my_loader(lua_State* state) {
// get the module name
const char* name = lua_tostring(state);
// find if you have such module loaded
if (mymodules.find(name) != mymodules.end())
{
luaL_loadbuffer(state, buffer, size, name);
// the chunk is now at the top of the stack
return 1;
}
// didn't find anything
return 0;
}
// When you load the lua state, insert this into package.loaders
http://www.lua.org/manual/5.1/manual.html#pdf-package.loaders
A pretty straightforward C++ function that would mimic require could be: (pseudocode)
int my_require(lua_State* state) {
// get the module name
const char* name = lua_tostring(state);
// find if you have such module loaded
if (mymodules.find(name) != mymodules.end())
luaL_loadbuffer(state, buffer, size, name);
// the chunk is now at the top of the stack
lua_call(state)
return 1;
}
Expose this function to Lua as require and you're good to go.
I'd also like to add that to completely mimic require's behaviour, you'd probably need to take care of package.loaded, to avoid the code to be loaded twice.
There is no package.loaders in lua 5.2
It called package.searchers now.
#include <stdio.h>
#include <string>
#include <lua.hpp>
std::string module_script;
int MyLoader(lua_State *L)
{
const char *name = luaL_checkstring(L, 1); // Module name
// std::string result = SearchScript(name); // Search your database.
std::string result = module_script; // Just for demo.
if( luaL_loadbuffer(L, result.c_str(), result.size(), name) )
{
printf("%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
return 1;
}
void SetLoader(lua_State* L)
{
lua_register(L, "my_loader", MyLoader);
std::string str;
// str += "table.insert(package.loaders, 2, my_loader) \n"; // Older than lua v5.2
str += "table.insert(package.searchers, 2, my_loader) \n";
luaL_dostring(L, str.c_str());
}
void SetModule()
{
std::string str;
str += "print([[It is add.lua]]) \n";
str += "return { func = function() print([[message from add.lua]]) end } \n";
module_script=str;
}
void LoadMainScript(lua_State* L)
{
std::string str;
str += "dev = require [[add]] \n";
str += "print([[It is main.lua]]) \n";
str += "dev.func() \n";
if ( luaL_loadbuffer(L, str.c_str(), str.size(), "main") )
{
printf("%s", lua_tostring(L, -1));
lua_pop(L, 1);
return;
}
}
int main()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
SetModule(L); // Write down module in memory. Lua not load it yet.
SetLoader(L);
LoadMainScript(L);
lua_pcall(L,0,0,0);
lua_close(L);
return 0;
}
I am using Turbo C. for below program when I debug code I always get the "Cannot read file" on output window. Input path of file is given as "PR1.txt" and same file present on C: as well.
#include "stdio.h"
#include "stdlib.h"
void main(void)
{
FILE *fp;
int value;
char ch;
fp = fopen("PR1.txt","w");
if(!fp)
{
printf("Cannot read file");
}
else
{
printf ("\n entr char to wrtite in file ::");
scanf("%c",&value);
fputc(ch,fp);
fclose(fp);
fp=fopen("PR1.c","r") ;
value=getc(fp);
printf("\n The result is= %d",value);
fclose(fp);
getch();
}
By default, your program will try to find the file in the location where you are executing the program. So make sure your data file is in the same folder or put the full path with the filename.
I want to save (pipe/copy) a BIO into a char array.
When I know the size it works, but otherwise not.
For example, I can store the content of my char* into a BIO using this
const unsigned char* data = ...
myBio = BIO_new_mem_buf((void*)data, strlen(data));
But when I try to use SMIME_write_CMS which takes a BIO (what I've created before) for the output it doesn't work.
const int SIZE = 50000;
unsigned char *temp = malloc(SIZE);
memset(temp, 0, SIZE);
out = BIO_new_mem_buf((void*)temp, SIZE);
if (!out) {
NSLog(#"Couldn't create new file!");
assert(false);
}
int finished = SMIME_write_CMS(out, cms, in, flags);
if (!finished) {
NSLog(#"SMIME write CMS didn't succeed!");
assert(false);
}
printf("cms encrypted: %s\n", temp);
NSLog(#"All succeeded!");
The OpenSSL reference uses a direct file output with the BIO.
This works but I can't use BIO_new_file() in objective-c... :-/
out = BIO_new_file("smencr.txt", "w");
if (!out)
goto err;
/* Write out S/MIME message */
if (!SMIME_write_CMS(out, cms, in, flags))
goto err;
Do you guys have any suggestion?
I would suggest trying to use SIZE-1, that way you are guaranteed that it is NULL terminated. Otherwise, it is possible that it is just over running the buffer.
out = BIO_new_mem_buf((void*)temp, SIZE-1);
Let me know if that helps.
Edit:
When using BIO_new_mem_buf() it is a read only buffer, so you cannot write to it. If you want to write to memory use:
BIO *bio = BIO_new(BIO_s_mem());