My text file is formated like that:
my.txt
Red
Green
Blue
Yellow
I\'m tring to get words like that:
typedef char * string;
You'll need to allocate memory for your null-terminated strings.
At the moment you are only allocating memory for 4 char *
, but these pointers are uninitialized and therefor will result in UB (undefined behavior) when you try to write data to the memory pointed to by them.
Working example snippet
The use of "%127s" in the below snippet is to prevent us writing outside the bounds of the allocated memory. With the format-string in question we will at the most read/write 127 bytes + the null-terminator.
Please remember that further error checks should be implemented if this is to be used in "real life".
file_handle
is indeed valid after attempt to open the filemalloc
did indeed allocate requested memoryfscanf
read the desired input#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int
main (int argc, char *argv[])
{
int i;
char * lines[4];
FILE *file_handle = fopen ("my.txt", "r");
for (i =0; i < 4; ++i) {
lines[i] = malloc (128); /* allocate a memory slot of 128 chars */
fscanf (file_handle, "%127s", lines[i]);
}
for (i =0; i < 4; ++i)
printf ("%d: %s\n", i, lines[i]);
for (i =0; i < 4; ++i)
free (lines[i]); /* remember to deallocated the memory allocated */
return 0;
}
output
0: Red
1: Green
2: Blue
3: Yellow
Since all the other answers told you what you did wrong but not how to fix it. Here
typedef char * string;
#define LEN 100 //long enough for your line
main(){
int i;
string array[4];
for(i = 0; i < 4; i++) {
if((array[i] = (char *)(malloc(sizeof(char) * LEN))) == NULL) {
printf("malloc failed");
return 1;
}
}
FILE *my;
my = fopen("my.txt","r");
for(i = 0; i < 4; i++)
fscanf(data, "%s", &array[i]);
fclose(my);
}
And like they said you made space for the pointers but not for what the pointers point to.
You try to read some data, but you don't have anywhere to put it. All you have is 4 pointers, pointing to god knows where and you are trying to write into it!
There are many ways to do this:
You know the bound to the size of the data:
#include <stdio.h>
#define MAX_CHARS 20
typedef char string[MAX_CHARS+1]; // leave one space for '\0'
main(){
int i;
string array[4];
FILE *my;
my = fopen("my.txt","r");
for(i = 0; i < 4; i++)
fscanf(data, "%s", array[i]); // no need for & with %s
fclose(my);
}
Assume a bound to the size of the data, and ignore the rest of the strings (if it was too big):
#include <stdio.h>
#define MAX_CHARS 20
#define MAX_CHARS_STR "20" // there are better ways to get this
typedef char string[MAX_CHARS+1];
main(){
int i;
string array[4];
FILE *my;
my = fopen("my.txt","r");
for(i = 0; i < 4; i++){
fscanf(data, "%"MAX_CHARS_STR"s", &array[i]); // read at most 20 chars for the string
ungetc('x', data); // append one character to make sure we don't hit space
fscanf(data, "%*s"); // ignore whatever is left of string
}
fclose(my);
}
Read the file twice, first time find out the sizes of each string (or the maximum size, for simplicity), then allocate memory for the strings (using malloc
). Then read the file again and this time actually store the strings:
#include <stdio.h>
typedef char *string;
main(){
int i;
string array[4];
int cur_size = 0;
FILE *my;
my = fopen("my.txt","r");
for(i = 0; i < 4; i++){
fscanf(data, "%*s%n", &cur_size);
array[i] = malloc((cur_size+1)*sizeof(*array[i]));
}
fclose(my);
my = fopen("my.txt","r");
for(i = 0; i < 4; i++){
fscanf(data, "%s", array[i]);
}
fclose(my);
// and when done:
for(i = 0; i < 4; i++){
free(array[i]);
}
}
Read from the input chunk by chunk. For each string, if input string was not finished yet resize the memory allocated for the string (increase its size), read another chunk and check again. Method 3 is faster though and I recommend it, but just so you know, this is basically what happens in C++'s string
.