Parse string " comes from a file " to integer - c

I am making a program in C that reads a line from file and displays this line on screen
My homework requires that the file must get a number from the file and make some operations on it.
I get the file content and put it in an array:
while ( fgets ( line, sizeof line, file ) != NULL )
{
strcpy(arra[i], line);
printf("array ----> %d \n", arra[i]);
i++;
}
how can I parse this content to int ?

If line is a char*, you can use atoi to convert it to an integer.
printf("array ----> %d \n", atoi(line));

you can use atoi()
int x = atoi("string");
From your code sample
while ( fgets ( line, sizeof line, file ) != NULL )
{
strcpy(arra[i], line);
printf("array ----> %d \n", atoi(arra[i]));
i++;
}

#include <stdio.h>
#include <stdlib.h>
#define MAX_DATA_SIZE 10
int main(){
FILE *file;
char line[128];
int array[MAX_DATA_SIZE];
int i,count,sum;
file = fopen("data.txt","r");
/* data.txt:
100
201
5
-6
0
*/
for(i=0; NULL!=fgets(line, sizeof(line), file); ++i){
if(i == MAX_DATA_SIZE){
fprintf(stderr,"exceeded the size of the array.\n");
exit(EXIT_FAILURE);
}
array[i]=atoi(line);
}
fclose(file);
/*some operations */
count = i;
sum = 0;
for(i=0;i<count;++i)
sum += array[i];
printf("%d\n",sum);
return 0;
}

Related

Reading and storing values from csv file in an array using C

#include <stdio.h>
#include <stdlib.h>
int main() {
int c1[100];
char c2[150];
char c3[100];
float c4[100];
float c5[100];
float c6[100];
float c7[100];
char c8[100];
char c9[100];
float c10[100];
char string[10][100];
int i, j;
char c;
FILE *fp1;
fp1 = fopen("sample.csv", "r");
while (1) {
c = fgetc(fp1);
if (c == EOF)
break;
else
printf("%c", c);
}
for (i = 1; i <= 10; i++) {
fscanf(fp1, "%d,%[^,],%[^,],%[^,],%[^,],%d,%d",
&c1[i], &c2[i], &c3[i], &c4[i], &c5[i],
&c6[i], &c7[i], &c8[i], &c9[i], &c10[i]);
}
for (j = 0; j <= 10; j++) {
printf("\n");
printf("%d", c3); //Here i am trying to read the column3 values but getting random integer values.
//This problem continues to every column
}
return 0;
}
I have to read file sample.csv and store values into the array so that I can perform operation on that values.
I am not getting the exact value from the csv file that I have read.
I am getting some random integer value on running the program.
There are many problems in your code:
you do not check if fopen() succeeded.
c must be defined as int for proper end of file testing
you must rewind the file with rewind(fp1); or fseek(fp1, 0L, SEEK_SET); before reparsing the contents with fscanf()
the loop index i must start at 0 instead of 1, because arrays are 0 based.
it is idiomatic in C to use for (i = 0; i < 10; i++) ... to handle 10 lines of input. i <= 10 would iterate 11 times.
you must check the return value of fscanf() to ensure the input stream has the expected format. The format string does not handle empty text fields.
the fscanf() format string is incompatible with the arguments provided
the printf format string "%d\n" in incompatible with the type of the argument: the argument is the array c3 which is passed as a pointer to its first member, not an int as expected.
Simply read a line in a loop until there are no more lines
#include <stdio.h>
#include <string.h>
#define MAX_ITEMS 10000
#define LARGEST_LINE 1000
#define LARGEST_ELEMENT 100
int main(void) {
int c1[MAX_ITEMS];
char c2[MAX_ITEMS][LARGEST_ELEMENT+1]; // large enough for each `c2`
char c3[MAX_ITEMS][LARGEST_ELEMENT+1];
char c4[MAX_ITEMS][LARGEST_ELEMENT+1];
char c5[MAX_ITEMS][LARGEST_ELEMENT+1];
int c6[MAX_ITEMS];
int c7[MAX_ITEMS];
int tmpc1;
char tmpc2[LARGEST_ELEMENT+1];
char tmpc3[LARGEST_ELEMENT+1];
char tmpc4[LARGEST_ELEMENT+1];
char tmpc5[LARGEST_ELEMENT+1];
int tmpc6;
int tmpc7;
int lineno = 0;
char buf[LARGEST_LINE]; // large enough for the largest line
while (fgets(buf, sizeof buf, fp1)) {
++lineno;
// no error, process line
if (sscanf(buf, "%d,"
"%" LARGEST_ELEMENT "[^,],"
"%" LARGEST_ELEMENT "[^,],"
"%" LARGEST_ELEMENT "[^,],"
"%" LARGEST_ELEMENT "[^,],"
"%d,%d",
&tmpd1, tmpc2, tmpc3, tmpc4, tmpc5, &tmpd6, &tmpd7) == 7) {
// line ok, copy tmp variables and update indexes
c1[i] = tmpd1;
strcpy(c2[i], tmpc2);
strcpy(c3[i], tmpc3);
strcpy(c4[i], tmpc4);
strcpy(c5[i], tmpc5);
c6[i] = tmpd6;
c7[i] = tmpd7;
i++;
} else {
// line with error, you may want to report to the user
fprintf(stderr, "line %d with error.\n", lineno);
}
}
// read "error", probably EOF; close file and report
fclose(fp1);
for (int j = 0; j < i; j++) {
printf("item #%d: %d, %s-%s-%s-%s, %d %d\n",
c1[j], c2[j], c3[j], c4[j], c5[j], c6[j], c7[j]);
}
return 0;
}
Also consider putting all those c arrays inside a struct and make 1 single array of that structure.

Strok spaces using buffer/dynamic memory

how could I strtok at spaces while reading in data from a buffer? If my text file contained
1 23 50
45 50 30
2 15 30
and I decide to print the array with my code below, it will print line by line. How could I extend this to further divide the array into individual numbers for each index of the array? Eg.
1
23
50, etc...
I've tried playing around with strtok but I keep segfaulting and I wasn't sure where to fix it.
FILE * fp;
char buffer[5000];
int size = 0;
char **entireFile = NULL;
fp = fopen("file.txt","r");
entireFile = malloc(sizeof(buffer) * sizeof(char*));
while (fgets(buffer,5000,fp)!= NULL)
{
entireFile[size] = malloc(strlen(buffer)+1);
strcpy(entireFile[size],buffer);
size++;
}
I want entireFile[0] = 1, entireFile1 = 23
This can easily be accomplished with fscanf. Here is a pretty good reference for scanning in inputs.
#include <stdio.h>
int main(){
FILE *in = fopen("in.txt" , "r");
int hold;
/* Won't actually store values, but can be used for
value manipulation inbetween */
while ( fscanf(in, "%d", &hold) != EOF ){
printf("Scanned in %d\n", hold);
}
fclose(in);
return 0;
}
If you want this in an array form, add an incrementing integer and change the hold to an array.
#include <stdio.h>
int main(){
FILE *in = fopen("in.txt" , "r");
int hold[100], i=0; // Hold a maximum of 100 integers
while ( fscanf(in, "%d", &hold[i]) != EOF ){
printf("Scanned in %d\n", hold[i++]);
}
fclose(in);
return 0;
}
You could also do dynamic memory allocation like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
FILE *in = fopen("in.txt", "r");
int i=0, j;
char* fragments[2000];
char entry[100];
while ( fscanf(in, "%s", &entry[i]) != EOF ){
fragments[i] = malloc(sizeof(char) * (1 + strlen(entry)));
strcpy(fragments[i], &entry[i]);
i++;
}
for ( j = 0; j < i; j++ ){
printf("%s\n", fragments[j]);
}
fclose(in);
return 0;
}
This will read 1, 2, or 3 numbers on each line of your file. It uses the return value from sscanf to see how many numbers were read from each line. Of course, if there is any rogue non-numerical data, it will mess up.
#include <stdio.h>
int main(void)
{
FILE *fp;
int a, b, c;
int res;
char str [100];
if ((fp = fopen("file.txt", "rt")) == NULL)
return 1;
while(fgets(str, sizeof str, fp) != NULL) {
res = sscanf(str, "%d%d%d", &a, &b, &c);
if (res == 3)
printf ("3 values %d %d %d\n", a, b, c);
else if (res == 2)
printf ("2 values %d %d\n", a, b);
else if (res == 1)
printf ("1 value %d\n", a);
else
printf ("0 values\n");
}
fclose(fp);
return 0;
}
File content:
1 23 50
45 50 30
2 15 30
10 20
100
Program output:
3 values 1 23 50
3 values 45 50 30
3 values 2 15 30
2 values 10 20
0 values
1 value 100

Reading combinations of string and integer from file in C

I am novice to C langugage, so please bear with me. I've tried to read a file which contains strings but output obtained is single character.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define CALLOC(num, type) ((char*)calloc (num, sizeof(char)))
#define FREE(addr) (free((void*) (addr)))
int i, count;
char *x, *y, *z;
int main (void)
{
FILE *stream;
if ( (stream = fopen ( "test.txt", "r" )) == NULL )
{ printf ("Cannot read the new file\n");
exit (1);
}
count = 3;
x=CALLOC(count, char);
y=CALLOC(count, char);
z=CALLOC(count, char);
for ( i=0; i<count; i++ )
{ fscanf (stream,"%c %c %c", &x[i], &y[i], &z[i]);
printf ("\n %d %c %c %c ", i, x[i], y[i], z[i]);
}
FREE(x);
FREE(y);
FREE(z);
fclose (stream);
}
Input test.txt file contains
1 ab 1
2 aa 5
1 cc 1
current output
0 1 a b
1 1 2
2 a a
Expected output
0 1 ab 1
1 2 aa 5
2 1 cc 1
I doubt whether I should use a character array but it seems not working and I feel reading a int using char is acceptable. Here I require the expected output, for this any method/suggestion is appreciated.
%c reads in only one char. So it's not going to read ab as a single char. Your lines in file and your formats don't correctly to read an entire line.
A simple approach is to use fgets() and print the entire line:
char line[256];
i = 0;
while(fgets(line, sizeof line, stream))
{
printf ("%d %s", i, line);
i++;
}
By the way, macros for calloc and free are unnecessary. They really don't make the code any easier to read than directly using those functions.
And the casts in them are also unnecessary.
The problem is you have the scan file. %c read a 8bit value. You scanned 3 char, but the file is contain 4 characters. If you don't use to be the value of the x, y, z I don't understand why use malloc.
Here a working source:
#include <stdio.h>
#include <stdlib.h>
int main() {
int count,i;
char w,x,y,z;
FILE *stream;
if((stream = fopen("test.txt","r")) == NULL) {
printf("Cannot read the new file\n");
return 1;
}
count = 3;
for(i=0;i<count;++i) {
fscanf(stream,"%c %c%c %c\n",&w,&x,&y,&z);
printf("%d %c %c%c %c\n",i,w,x,y,z);
}
return 0;
}
for ( i=0;i<count; i++ )
{
fscanf (stream,"%s %s %s", x, y, z);
printf ("\n %d %s %s %s ", i, x, y, z);
}
You can modify your loop to this.This loop will read file until end of file and you have to use %s as ab is a string not charater so it can't be stored in a char variable.

Reading from file C programing

I'd appreciate any help I can get. I'm not sure I completely understand this program. I also get the following errors when I try to run it.
I was also told that on line 15 I was trying to mod a char array. What should I be doing? Thanks for taking a look.
structFinal.c: In function print_part':
structFinal.c:14: error: invalid operands to binary %
structFinal.c: In function main':
structFinal.c:36: error: syntax error before ']' token
#include <stdio.h>
#define NAME_LEN 25
typedef struct {
int number;
char name[NAME_LEN+1];
int on_hand;
} part;
void print_part(part p[], int ind) {
int i;
printf("Whole List\n");
for(i = 0; i< ind; i++)
{
if(p[ind].name % 2 == 0)
printf("Part number: %d\n", p[ind].number);
printf("Part name: %s\n", p[ind].name);
if(p[ind].on_hand < 5)
printf("Quantity on hand: %d\n", p[ind].on_hand);
}
printf("%d\n", p[ind].number);
fgets(p[ind].name,50,fp);
fscanf(fp, "%d", &p[ind].on_hand);
printf("%s\n----%d\n", p[ind].name, p[ind].on_hand);
ind++;
fscanf(fp, "%d", &p[ind].number);
a = fgetc(fp);
} print_part(p[ ] , ind);
fclose(fp);
return 0;
Edit: I just tried this on my Ubuntu machine in Netbeans and it ran. We're suppose to run this in Unix and that's were it fails. I'm lost.
Edit: This is my final file so far. I'm pretty sure this works.
#include <stdio.h>
#define NAME_LEN 25
typedef struct {
int number;
char name[NAME_LEN+1];
int on_hand;
} part;
void print_part(part p[], int ind) {
int i;
printf("Whole List\n");
for(i = 0; i< ind; i++)
{
printf("Part number: %d\n", p[i].number);
printf("Part name: %s\n", p[i].name);
printf("Quantity on hand: %d\n", p[i].on_hand);
}
}
int main() {
/* first try, input only one set and print it */
part p[50];
int ind=0;
FILE *fp;
fp = fopen("structTest.txt", "r");
fscanf(fp, "%d", &p[ind].number);
char a;
a = fgetc(fp); /* extract the return symbol out of input buffer */
while (p[ind].number != 0)
{
while (a != '\n')
{
a = fgetc(fp);
}
printf("%d\n", p[ind].number);
fgets(p[ind].name,50,fp);
fscanf(fp, "%d", &p[ind].on_hand);
printf("%s\n----%d\n", p[ind].name, p[ind].on_hand);
ind++;
fscanf(fp, "%d", &p[ind].number);
a = fgetc(fp);
}
print_part(p , ind);
fclose(fp);
return 0;
}
/*
the code is fixed so it will extact all white spaces after a part number
is typed. the getchar while loop will keep get one character to var a
until a return key is reached
*/
Here you have some character at the end. Notices this ` which doesn't belong there?
if(p[ind].name % 2 == 0)`
And this
print_part(p[ ] , ind);
should be
print_part(p , ind);
p[ind].name is a characters array, you cannot run modulu operation on it.
You can run % on numbers - integers.
What would a logical meaning be of doing module on a string? (char array)
Say you have the array contents of abcde what is abcde % 2?

handling trailing \n when using feof()

I have written a small program which takes input of a file such as:
13,22,13,14,31,22, 3, 1,12,10
11, 4,23, 7, 5, 1, 9,33,11,10
40,19,17,23, 2,43,35,21, 4,34
30,25,16,12,11, 9,87,45, 3, 1
1,2,3,4,5,6,7,8,9,10
and outputs the largest sum of numbers on each line that is less than 50.
However if the inputted file has a trailing newline character the loop runs one too many times and hence another line is added to the array with random data. So I'm looking for a better way to do this comparison to avoid this issue. I'm also assuming all lines have 10 integers on at the moment as i cannot think of a better way to do the end of line loop comparison.
#include <stdio.h>
#include <stdlib.h>
void readLineData(int lineNo, int val[][10], FILE *fp);
int findSum(int lineNo, int val[][10], FILE *fp);
int main(int argc, char *argv[]) {
FILE *fp;
int val[5][10];
// Open file.
if ((fp = fopen(argv[1], "r")) == NULL)
{
perror("Cannot open file ");
exit(EXIT_FAILURE);
}
for (int i = 0; !feof(fp); i++) // runs too many times if file ends with '\n'
{
readLineData(i, val, fp);
printf("%d\n", findSum(i, val, fp));
}
fclose(fp);
return EXIT_SUCCESS;
}
void readLineData(int lineNo, int val[][10], FILE *fp) {
char c;
for (int i = 0; i < 10; i++) // assuming line contains 10 integers
{
fscanf(fp, "%d,", &val[lineNo][i]);
}
}
int findSum(int lineNo, int val[][10], FILE *fp) {
int highVal = 0;
int value1 = 0;
int value2 = 0;
for(int i = 0; i < 10; i++) //each letter
{
for(int j = 0; j < 10; j++)// every other letter
{
if((val[lineNo][i] + val[lineNo][j]) > highVal && i != j && (val[lineNo][i] + val[lineNo][j]) <= 50)
{
highVal = val[lineNo][i] + val[lineNo][j];
value1 = val[lineNo][i];
value2 = val[lineNo][j];
}
}
}
printf("Line %d: largest pair is %d and %d, with a total of: ", lineNo+1, value1, value2);
return highVal;
}
any help with those loop comparisons and general notation tips is most welcome.
Thanks
The posted code does not distinguish between two lines that have five integers and (the expected) one line that has 10 integers. Suggest reading in a line at a time, using fgets() and then using sscanf() on the read line to ensure that all the read integers belong to the same line.
Check the return value of input operations. For example, sscanf() (and fscanf()) return the number of assignments made. Only process lines that have the expected 10 integers, which would detect invalid lines including the trailing empty line.
For example:
/* Returns 1 on success and 0 on failure. */
int readLineData(int lineNo, int val[][10], FILE *fp)
{
char line[1024]; /* Arbitrarily large. */
if (fgets(line, sizeof(line), fp))
{
/* %n records position where processing ended. */
int pos;
const int result = sscanf(line,
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d%n",
&val[lineNo][0],
&val[lineNo][1],
&val[lineNo][2],
&val[lineNo][3],
&val[lineNo][4],
&val[lineNo][5],
&val[lineNo][6],
&val[lineNo][7],
&val[lineNo][8],
&val[lineNo][9],
&pos);
/* 10 integers and full line processed,
except if new-line character present. */
return 10 == result &&
(pos == strlen(line) ||
(pos + 1 == strlen(line) && '\n' == line[pos]));
}
return 0;
}
You could simply consume the newline character yourself:
for (int i = 0; !feof(fp); i++) // runs too many times if file ends with '\n'
{
readLineData(i, val, fp);
printf("%d\n", findSum(i, val, fp));
fscanf(fp, "%*c"); // read a character without storing it in a variable
}
Note that there are undoubtedly better ways that involve reading an entire line at once and simply examining its contents; but this is the easiest way that will fit with what you already have.
you could check if fscanf fails in your readLineData function:
int readLineData(int lineNo, int val[][10], FILE *fp) {
for (int i = 0; i < 10; i++) {// assuming line contains 10 integers
if (fscanf(fp, "%d,", &val[lineNo][i]) != 1) {
return 1;
}
}
return 0;
}

Resources