how to load a c string from a file - c

my code keeps throwing a segmentation fault from internal c libraries, my code is the following:
char *vertexShaderCode = (char *)calloc(1024, sizeof(char));
FILE *shaderFile;
shaderFile = fopen("./shaders/vertex.glsl", "r");
if(shaderFile)
{
//TODO: load file
for (char *line; !feof(shaderFile);)
{
fgets(line, 1024, shaderFile);
strcat(vertexShaderCode, line);
}
it is meant to load all the data from a file as a c string, line by line. can anyone help?

You want this:
char *vertexShaderCode = (char *)calloc(1024, sizeof(char));
FILE *shaderFile;
shaderFile = fopen("./shaders/vertex.glsl", "r");
if (shaderFile == NULL)
{
printf("Could not open file, bye.");
exit(1);
}
char line[1024];
while (fgets(line, sizeof(line), shaderFile) != NULL)
{
strcat(vertexShaderCode, line);
}
You still need to make your that there is no buffer overflow. Possibly you need touse realloc in order to expand the buffer if the initial length of the buffer is too small. I leave this as an exercise to you.
Your wrong code:
char *vertexShaderCode = (char *)calloc(1024, sizeof(char));
FILE *shaderFile;
shaderFile = fopen("./shaders/vertex.glsl", "r"); // no check if fopen fails
for (char *line; !feof(shaderFile);) // wrong usage of feof
{ // line is not initialized
// that's the main problem
fgets(line, 1024, shaderFile);
strcat(vertexShaderCode, line); // no check if buffer overflows
}

Related

Segmentation fault when reading file in c in a small file

I got segmentation fault ( core dumped) in c while reading a file.i used this code for milion other files and it workes fine. But this file has 138 lines when others start at 250. So im guessing thats the problem? (the code is on the bottom of my post)its suppose to help me work on the read data so i could do operations on them in the code but whatever i do its just "core dumped"
it breaks here :
while (fgets(line, sizeof line, fp) != NULL) {
strtok(line, "\n");
parseLine(line, &dataList);
}
i already tried :
char *line = malloc( sizeof(char) * ( LINE_BUFFER + 1 )
instead of
char line[LINE_BUFFER];
Heres the part of the code that reads a file :
#define DIFF_BUFFER 99999999
DataLineNode *loadData(const char *fileName) {
FILE *fp;
char line[LINE_BUFFER];
DataLineNode *dataList = NULL;
fp = fopen(fileName, "r");
if (fp == NULL) {
printf("No file '%s'.\n", fileName);
exit(EXIT_FAILURE);
}
while (fgets(line, sizeof line, fp) != NULL) {
strtok(line, "\n");
parseLine(line, &dataList);
}
fclose(fp);
return dataList;
}
````

segfaulting with fgets, even though fopen doesn't return NULL in C

I've looked all over and made sure there were no warnings, but my code to replace text with digits keeps returning segfault. Any help?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc , char *argv[])
{
FILE *file;
file = fopen(argv[1] , "r");
char *line = malloc(1024);
if(file != NULL)
{
while(fgets(line , sizeof(line) , file))
{
//things
}
}
else
{
printf("ERROR: %s NOT AVAILABLE" , argv[1]);
}
return 0;
}
Replace:
char *line = malloc(1024);
with:
char line[1024] = {0};
or:
char line[1024];
if you don't want to clear out the line buffer.
Otherwise, you end up with two problems.
First:
sizeof(line)
returns the size of the pointer (4 or 8 bytes). That's not what you want.
Second: You have a memory leak because you don't free the line pointer at the end.
You can use malloc if you want, but you want to write clean(er) code to do this. You might do something like:
#define MAX_LINE_LENGTH 1024
/* ... */
char *line = NULL;
line = malloc(MAX_LINE_LENGTH);
if (!line) {
fprintf(stderr, "Error: Could not allocate space for line buffer!\n");
exit(EXIT_FAILURE);
}
FILE *file = NULL;
/* Avoid undefined behavior by making sure filename argument holds a value */
if (argv[1])
file = fopen(argv[1] , "r");
if (file != NULL) { /* You could also do "if (file) { ... }" */
while (fgets(line, MAX_LINE_LENGTH, file)) {
/* ... */
}
}
free(line);
line = NULL;
As a habit, explicitly initialize pointers to NULL, and check that they actually hold a value before using them. Welcome to C!

Segmentation fault 11 in C on mac

I am unable to read the data from the file created. This is a very simple code and I simply cannot understand why it is not working. I have just shifted to mac and installed the developer command line tools.
My code is :
int main()
{
FILE *fp;
int lines = 0;
char *data;
data = (char *)malloc(1000);
data = NULL;
fp = fopen("1.txt", "r");
while (fgets(data, 1000, fp) != NULL)
{
printf("%s\n", data);
lines++;
}
printf("Lines = %d\n", lines);
free(data);
fclose(fp);
return 0;
}
You allocate space for data and then promptly leak it.
char *data;
data = (char *)malloc(1000);
data = NULL;
You then use fgets() with a NULL pointer, which causes undefined behavior.
fgets(data, 1000, fp)
Perhaps you should remove this line of code?
data = NULL;

runtime-error "access violation writing location " with strcpy function

i have this run time error "access violation writing location " with strcpy function
Here part of my code:
else if (strcmp(sentenceRecv, "405002") == 0){
/*winVersion[SIZE] = (char*)malloc(sizeof(tempString));*/
system("ver >> text.txt");
FILE *pfile = fopen("text.txt", "rt+");
if (pfile == NULL)
{
printf("Couldn't open file\n");
}
fread(tempString, sizeof(char), SIZE - 1, pfile);
fclose(pfile);
pfile = fopen("text.txt", "w");
if (pfile == NULL)
{
printf("Couldn't open file\n");
}
fputc((int)' ', pfile);
fclose(pfile);
/* winVersion[SIZE] = strdup(tempString);*/
strcpy(winVersion, tempString);
send(ClientSocket, winVersion, sizeof(winVersion), 0);
menuCheck = 1;
}
The error is in this line:strcpy(winVersion, tempString);
and in the first lines i write:
char winVersion[SIZE];
char tempString[SIZE];
char tempString[SIZE] = {0};
strcpy() needs a null-terminated string ('\0')
Otherwise it will just keep going until it hits a '\0' somewhere in the contiguous memory which may not belong to your program hence the access violation error.
You could use char *strncpy(char *dest, char *src, size_t n); and specify SIZE as the n number of bytes to copy. This is still somewhat unsafe because the copied strings won't be null-terminated either and could cause more problems later.
http://beej.us/guide/bgc/output/html/multipage/strcpy.html

Issue with fwrite and fread

Having an issue with my fwrite() and fread() dealing with a binary file here is my source code, and towards the bottem are my read and write. Right now it is returning 'jake' when I run it, and nothing else. I was told to write a dump buffer function to deal with the binary characters. In addition here is the text file as well, I am writing to a blank file called info.bin. PS I know that it is bad practice to save the zip as an int but this is what my professor is asking for.
File:
mike|203-376-5555|7 Melba Ave|Milford|CT|06461
jake|203-555-5555|8 Melba Ave|Hartford|CT|65484
snake|203-555-5555|9 Melba Ave|Stamford|CT|06465
liquid|203-777-5555|2 Melba Ave|Barftown|CT|32154
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LINE 80
#define RECORDS 10
struct info{
char name[100];
char number[100];
char address[100];
char city[100];
char state[100];
int zip;
};
void dump_buffer(void *buffer, int buffer_size)
{
int x;
for(x = 0; x < buffer_size; x++)
{
printf("%c",((char *)buffer)[x]);
}
}
int i, j, seeker;
int main(int argc, char* argv[])
{
char *buffer;
struct info input_records[RECORDS];
int nrecs = 0;
unsigned long fileLen;
char line[LINE];
FILE *fp = NULL;
FILE *fpbin = NULL;
FILE *fpread = NULL;
if (argc != 2)
{
printf ("ERROR: you must specify file name!\n");
return 1;
}
/* Open file */
fp = fopen(argv[1], "r");
if (!fp)
{
perror ("File open error!\n");
return 1;
}
while (!feof (fp)) {
fgets(line, sizeof(line),fp);
char* tok = strtok(line, "|");
while(tok != NULL)
{
strcpy(input_records[nrecs].name, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].number, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].address, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].city, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].state, tok);
tok = strtok(NULL, "|");
input_records[nrecs].zip = atoi(tok);
tok = strtok(NULL, "|");
}
nrecs++;
}
fpbin = fopen("info2.bin", "wb");
if (!fp)
{
perror ("File open error!\n");
return 1;
}
for(i = 0; i < 4; i++)
{
fwrite(&input_records[i], sizeof(struct info), 200000, fpbin);
}
fclose(fpbin);
fpread = fopen("info2.bin", "rb");
fseek(fpread, 0, SEEK_END);
fileLen = ftell(fpread);
fseek(fpread, 0, SEEK_SET);
buffer = (char *)malloc(sizeof(struct info));
fread(buffer, fileLen, 1, fpread);
dump_buffer(buffer, sizeof(buffer));
fclose(fpread);
fclose(fp);
free(buffer);
return 0;
}
fwrite(&input_records[i], sizeof(struct info), 200000, fpbin);
You just told fwrite to write 200000 * sizeof(struct info) bytes to the file, starting at the address of input_records[i]. That accesses memory far beyond what has been allocated for input_records, the behaviour is undefined, but a segmentation fault is not unlikely. I'm actually surprised that apparently it didn't crash for you.
buffer = (char *)malloc(sizeof(struct info));
fread(buffer, fileLen, 1, fpread);
You're trying to read fileLen bytes into a buffer of size sizeof(struct info). If fileLen > sizeof(struct info), that is again undefined behaviour, and if fileLen is sufficiently larger, likely to crash.
You should let fwrite one object of size sizeof(struct info) each time, and you should allocate fileLen bytes for the buffer you read in (or read in chunks of size sizeof(struct info)). And you should check the return values of fwrite and fread to know whether they succeeded in writing/reading the desired data and handle failures appropriately.
fpbin = fopen("info2.bin", "wb");
if (!fp)
{
You check the wrong FILE* here, and you don't check fpread at all.
Further, you pass the wrong count to dump_buffer,
dump_buffer(buffer, sizeof(buffer));
buffer is a char*, so sizeof buffer is the size of a char*, typically four or eight bytes. You should pass the allocated size of the buffer there.
And, when reading the original file,
while (!feof (fp)) {
fgets(line, sizeof(line),fp);
feof(fp) only becomes true after an attempt to read was made when the end of the file has been reached, you should change your loop condition to
while(fgets(line, sizeof line, fp) != NULL) {
Finally, your tokenizing code will fail badly if the input file contains malformed data, or too long lines. You should also add checks there, so that you don't pass a NULL to strcpy or atoi.

Resources