How to read individual characters from a file into an array - arrays

Newbie here. I need to create a program that reads strings from a textfile.txt then processes a few characters from it.
The contents of textfile.txt is as below.
JA100200300
FE111222333
MA101202303
I need to reference "JA","100", "200" and "300" separately. I managed to do this with the code below, where I split the string into 11 characters and put it into array. Of course this code works only as you type out the string. I need a way to do the same thing but get the string from a file instead.
while((a[i++]=getchar()) != '\n' && i < 11);
How do I do this? Can I read the file and put each line of string into an array, then read from the array and split each array into multiple arrays? Is that possible? Or read each character from the file and put them into arrays something like fscanf %d but split each character?

You might want something like this:
FILE fp = fopen("data.txt","r");
char line[100] = { 0 }, str1[3], str2[4], str3[4], str4[4];
if (!fp) {
perror("opening file");
exit(1);
}
while(fgets(line,sizeof line,fp)) {
strncpy(str1,line,2);
str1[2] = '\0';
strncpy(str2,&line[2],3);
str2[3] = '\0';
strncpy(str3,&line[5],3);
str3[3] = '\0';
strncpy(str4,&line[8],3);
str4[3] = '\0';
}

Related

Copying a desired string from a text file in C

I have read all the text from a desired file and it is now stored in buff. I want to copy just the string content after identifier strings such as 'Title'.
Example file below:
"Title: I$_D$-V$_{DS}$ Characteristic Curves (Device 1)
MDate: 2016-03-01
XLabel: Drain voltage V$_{DS}$
YLabel: Drain current I$_D$
CLabel: V$_{GS}$
XUnit: V
... "
for(;;) {
size_t n = fread(buff, 1 , DATAHOLD, inFile);
subString = strstr( buff, "Title");
if( subString != NULL) {
strcpy(graph1.title , (subString + 7));
subString = NULL;
}
....more if statements....
if( n < DATAHOLD) {
break;
}
}
I understand that strstr() returns a pointer to location of the search string, I added 7 to get just the text that comes after the search string and this part works fine. The problem is strcpy() copies the rest of buff character array into graph1.title.
How to instruct strcpy() to only copy the text on the same line as the substring pointer? Using strtok() maybe?
I agree with ChuckCottrill, it would be better if you read and process one line at a time.
Also since the file you are dealing with is a text file, you could be opening it in text mode.
FILE *fin = fopen("filename", "r");
Read a line with fgets() into a string str. It should be noted that fgets() will take the trailing \n' to str.
fgets(str, sizeof(str), fin);
char *substring;
if( (substring = strstr(str, "Title: ")) != NULL )
{
strcpy(graph1.title, substring+strlen("Title: "));
}
At this point, graph1.title will have I$_D$-V$_{DS}$ Characteristic Curves (Device 1) in it.
Read and process a single line at a time.
for( ; fgets(line,...); ) {
do stuff on line
}
You could use another strstr to get the position of the end of the line, and then use strncpy which is like strcpy, but accepts a third argument, the number of chars to copy of the input.

reading strings from file to struct array in C

I am trying to read strings from file and add them to my array of structs but when i do i get some random characters at the end of one or two strings.Here is my code for reading strings line by line:
while ((read = getline(&line, &len, fp)) != -1) {
strncpy(&structures[i].id,line,4); //copies the first four characters to my array of structures
...
}
When i print out the structures[0].id it prints "WW23�" when it should be just "WW23".It does that with couple of strings, although not with all of them.
My struct looks like this.
struct observers
{
char id[13];
...
};
It reads from file properly at least it gets the integer values right.
You are not terminating the string. Add '\0' at the end structures[i].id[4] = '\0'. It should work fine.
You probably need to add '\0' as the 5'th character to terminate the string.

Load file into 2D char Array in C

I have a text file with 25 lines, each with 34 characters on.
In C how is it possible to load these characters and store them into a 2D array?
If the first three lines of the file are such:
bamaaaaaaaacxxxxxxxxxxbaaaaaaaamac
jzjzzzzzzzzdaaaaaaaaaaezzzzzzzzjzj
jzjzbaaczgzzzzzzzzzzzzzzgzbaaczjzj
...and so on
I require the array to be stored as if it was defined like this:
char* data[] = {
"baaaaaaaaaaaaaacxxbaaaaaaaaaaaaaac",
"jzzzzzzzzzzzzzzjxxjzzzzzzzzzzzzzzj",
"jzbaaaaaaaaaaaaexxdaaaaaaaaaaaaczj",
...and so on
Hopefully this makes some sense! It is important that the type of data is char data[][] as it is used in that format in the rest of my project and cannot be changed.
I have done the basic begining of the File IO
FILE *infp;
printf("Opening file\n");
if((infp = fopen("file.txt", "r"))== NULL) {
printf("\nERROR : Unable to open input file\n");
SetExitWithCode( 999 );
}else{
//code here
}
Can anyone help?
So, you want your array to look like this:
char data[25][35] //There is an extra 1 character per line to hold the null terminator character
Then simply read the whole file into that array
fread(data, 1, sizeof(data), infp);
And finally, replace the new line character in on each line with a terminator
for (int i = 0; i < 25; ++i) {
data[i][34] = 0;
}
This is the easiest solution to the problem, but it is also a bad way of doing it. It does not validate that the data is in the correct format, and everything is hard coded.

How does this work? About saving strings in array

I am trying to read a series of names from a text file and save them into an array.
Everything looked okay until I try to reference a specific name by using indexes (ex: array[0] ). It gives me t25.txt where it should of give me t1.txt. What did I do wrong?
Here's what I have:
#define MAX_STRING 25
FILE *in;
in = fopen("filenames.txt", "r");
if (!in) {
printf("Failed to open the file\n");
exit(1);
}
char array[MAX_STRING];
// In my mind, I want it to look like this:
// array[0] = t1.txt
// array[1] = t2.txt
int i;
for ( i = 0; i < MAX_STRING; i++ ) // Get 25 words
{
fscanf( in, "%s", array);
printf( "filename = %s\n", array);
// I print it out to make sure it's getting what i want and it did
}
My text file - filenames.txt is something like this
t1.txt
t2.txt
Thanks much
char array[MAX_STRING];
is an array of characters, not an array of strings. Your loop overwrites this array in every iteration. You might have meant something like
char array[N_STRINGS][MAX_LENGTH_OF_A_SINGLE_STRING];
You aren't saving multiple strings in one array, you are overwriting one string multiple times.
In C each string is saved as an array, so you have to have something like a 2D-Array: Dimension 1: the String, Dimension 2: The "array":
array[MAX_STRING][MAX_NAME_LEN]
This is what you intend to do!
You have to understand C-Strings as an Array of Characters in continous memmory, with a \0 at the end to identify the end of the "string". You are handling with arrays when you are handling with strings!
you define char array[MAX_STRING]; which simply defines one string
so
array[0] = 't'
array[1] = 'x'
What you need is char array[NUM_STRING][MAX_STRING]

printf limited to three characters?

I've stripped down this function to what's causing the problem, but I'll try to give enough context to this problem without making you peruse through lines and lines of text:
Basically, I am feeding a string into the function below, and if the first character in the string is a # then I want to print the string. That's it.
However, when doing this, the strings that are printed are cut at three characters in length. So for example, where the input string is "# Hello, World!" only "# H" will get printed.
I'm getting my input strings using fgets() from the following input file:
# Testing
#######
# More
And the output is as following:
# T
###
###
#
# M
Here are the relevant, trimmed functions:
int main(int argc,char *argv[]){
FILE *input;
lineResponse response;
//If a filename was specified, the file exists, and it is openable
if(argv[1] != NULL && (input = fopen(argv[1],"r")) != NULL){
char *currentLine = "";
//Loop through the lines
while(fgets(currentLine,sizeof(input),input)){
response = parseLine(currentLine);
}
}
fclose(input);
getchar();
}
lineResponse parseLine(char *line){
lineResponse response = {0,NULL}; //0 is the default lineType, denoting a line that cannot be parsed
if(line != NULL){
if(line[0] == '#'){
printf("%s\n",line);
}
}
return response;
}
The lineResponse return is irrelevant to this problem. What could be causing the trimming? If you need a more extensive example, I can provide one.
char *currentLine = "";
//Loop through the lines
while(fgets(currentLine,sizeof(input),input)){
This is your problem. You are declaring a char pointer and assigning it a string literal ... then trying to read into it. You also seem to not understand the second argument of fgets; it reads one less than that number of characters and terminates the buffer with a \0. Also be aware that newlines are stored in the buffer and need to be removed if you don't want them.
This should be:
char currentLine[1024]; /* arbitrary - needs to be big enough to hold your line */
while(fgets(currentLine,1024,input)) {
String literals (e.g. char* = "This is a string literal") are immutable (read-only). They are created at compile time.
The problem must be in how you are reading the line. Since you comment that you are reading with fgets(), I'm going to take a guess that you're on a 32-bit machine and you have some code something like:
char buffer[128];
if (fgets(&buffer, sizeof(&buffer), stdin))
{
lineResponse r = parseLine(buffer);
...
}
There are other vaguely similar techniques:
char *buffer;
if (fgets(buffer, sizeof(buffer), stdin))
...
What's going on here is that you're giving the wrong size (and wrong address) to fgets(), and it is seeing a size of 4 total, which means it can only store 3 characters plus the terminating NUL '\0'.
Correct code might be:
char buffer[128];
if (fgets(buffer, sizeof(buffer), stdin))
{
lineResponse r = parseLine(buffer);
...
}
Or:
char *buffer = malloc(2048);
// error check memory allocation!
if (fgets(buffer, 2048, stdin))
...
Now the code is visible...
Your code is shown as:
char *currentLine = "";
//Loop through the lines
while(fgets(currentLine,sizeof(input),input)){
response = parseLine(currentLine);
This indeed corresponds (more or less) to the char *buffer; version I hypothesized. You have an added tweak that you use sizeof(input) where you declare FILE *input;. You need to adapt my second suggested alternative if you keep currentLine as a char *, or alternatively (simpler because there is no dynamically allocated memory to leak), use:
char currentLine[2048];
//Loop through the lines
while (fgets(currentLine, sizeof(currentLine), input))
{
response = parseLine(currentLine);
...
}

Resources