Scanf not reading all numbers found in CSV in C - c

I am trying to read a CSV file of integers and count their number. However, the code executes this while loop once.
When i change the format of the file so that each number is on a separate line and no commas are there, it works. Can someone tell me where is my mistake? How can i make the loop work for CSV?
while(scanf("%d", &otherNum)==1)
{
count++;
printf("%d", otherNum);
}

As soon as "%d" hits a non-integer (comma, or any other character), it exits the while loop.
You will need to build the logic of parsing between "%d" and other characters inside of your loop.

Better use below codes
char num[50];
int otherNum = 0;
FILE *f = fopen("yourCSV.csv", "w");
while(fgets(num,sizeof num,f){
if(num[0] != ',')
{
otherNum = atoi(num);
printf("%d", otherNum);
}
}

Related

parsing text file of unknown size to array in c

i'm new programmer in c and need some help. I'm trying to read text file which contains numbers (long doubles) separated by ','. My problem is that I don't know what is the size of each line and every solution I find online assume it's size. This is a part of work I got to do and I can't use scanf/fscanf. finally I would like to have array contains the numbers (without the ','), what is the best way to do it?
Thanks a lot!
edited:
FILE *inputFile;
inputFile = fopen("C:\\Users\\studies\\C\\Exe1\\input_example.txt",
"r");
for (int c = 0; c < 7; c++) {
fscanf(inputFile, "%Lf,", &params[c]);
}
any other way I tried to read just didn't go well, fgets, getchar, etc..
Divide and conquer! See if you're able to read the file correctly without storing anything. Just read and print what you read, so you can compare your output with the input file. If they match, you're on your way.
It's easier than you think to read the file. Use a char array as a temporary buffer for each number and read the file character by into the buffer. If the input is a ',' then you have read a complete number. Same goes for the newline '\n'.
// untested snippet
char buf[1024]; // Make it big
size_t i = 0;
int c;
long double d;
while ((c = fgetc(fp)) != EOF) {
if (c == ',' || c == '\n') {
buf[i] = '\0';
d = strtold(buf);
printf("%lf%c", d, c); // debugging, sanity check
i = 0;
}
else
buf[i++] = c;
}
There may be uncovered corner cases which the snippet doesn't cover, like missing newline at end of file, or silly Windows \r\n combos. Also, string to double conversion needs proper error checking. Still, the snippet should get you going.

How to save every line in file (IN C) in a variable? :)

I need to save every line of text file in c in a variable.
Here's my code
int main()
{
char firstname[100];
char lastname[100];
char string_0[256];
char string[256] = "Vanilla Twilight";
char string2[256];
FILE *file;
file = fopen("record.txt","r");
while(fgets(string_0,256,file) != NULL)
{
fgets(string2, 256, file);
printf("%s\n", string2);
if(strcmp(string, string2)==0)
printf("A match has been found");
}
fclose(file);
return 0;
}
Some lines are stored in the variable and printed on the cmd but some are skipped.
What should I do? When I tried sscanf(), all lines were complete but only the first word of each line is printed. I also tried ffscanf() but isn't working too. In fgets(), words per line are complete, but as I've said, some lines are skipped (even the first line).
I'm just a beginner in programming, so I really need help. :(
You're skipping over the check every odd number of lines, as you have two successive fgets() calls and only one strcmp(). Reduce your code to
while(fgets(string_0,256,file) != NULL)
{
if( ! strcmp(string_0, string2) )
printf("A match has been found\n");
}
FWIW, fgets() reads and stores the trailing newline, which can cause problem is string comparison, you need to take care of that, too.
As a note, you should always check the return value of fopen() for success before using the returned pointer.

A dilemma with reading files in C

Its my first question, so I hope you guys can help. In class, I was tasked with writing a C code that reads a group of strings from 1 file, and print them in another file, along with the ASCII codes of each character in the string, and the sum of the ASCII code values. The code below compiled, but did not execute. Is the code right, but I did something wrong, or is the code simply wrong. Thanks a bunch.
Note: the first file reads from a text file named list, and the code prints into a text document named list2.
#include <stdio.h>
int main(void)
{
FILE *file1, *file2;
file1 = fopen("list.txt", "r");
if (file1==NULL)
{
puts(" File not exisiting\n");
}
file2 = fopen("list2.txt", "w");
if (file2==NULL)
{
puts(" File could not open \n");
}
char a[5];
fscanf(file1, "%s", a);
int b,c;
while (a[5]!=EOF)
{
for (int i=0;i<5;i++)
{
fprintf(file2, "%c", a[i]);
b=a[i];
fprintf(file2, "%d", b);
c+=b;
}
}
fprintf(file2, "%d", c);
return 0;
}
Point 1. With a definition like
char a[5];
using
while (a[5]!=EOF)
invokes undefined behaviour.
You're facing off-by-one error. Remember, array index in c starts from 0. The valid access it at most upto a[4].
Point 2. fscanf(file1, "%s", a); is unsafe. It can cause buffer overflow. Atleast, you need to write
if ( fscanf(file1, "%4s", a) != 1)
{
//scanning not successful, take necessary measures
}
//otherwise, continue nomal execution.
Point 3. The logic for while loop is not correct. You don't have a break condition there.
Point 4. c+=b;, here c is used uninitalized. read-before-write scenario. Again, undefined behaviour. Remember, auto local variables doesnot get initialized to 0 or some value automatically. You've to initialize explicitly.
Point 5. Do not continue normal execution if if (file1==NULL) condition satisfies. Only printing a message is not sufficient. You should discontinue the program and avoid using file1, file1 etc.
Credits for point 5: user4402433
Include return in the file check as
if (file1==NULL)
{
puts(" File not exisiting\n");
return 0;
}
as there is no use of proceeding with the code if any one of the file is opened.
Also initialize the value of c=0; before while so that any garbage value can be avoided.
The array a[] has to be indexed to update the file content. So place the
fscanf(file1, "%s", a[i]);
inside the for() loop . This is to avoid buffer overflow which occurs in rare cases.

Read whole digits not split

Hi guys how to read entire digits from file? I mean my input file is 100-4/2 and i wrote this code while(fscanf(in,"%s",s)!=EOF) but it read like this 1 0 0. I want read like 100. How to solve this?
It's probably because you are using one-byte character(ANSI) set while the file is written with two-byte characters(Unicode). If you have created the file with the same program that is reading it it's going to read it right, but if not, you can open the file you are reading in notepad, then click save as, and there you can choose ANSI or Unicode.
You can read the whole line at once using getline() or similar method (also you can read as you are doing if there is only one line, then when EOF is true, whole line is read). Then you can parse the line to extract numbers and operators.
Use "%d" for integers
int value;
if (scanf("%d", &value) != 1) /* error */;
printf("Value read is %d.\n", value);
The below is simple program is self explanatory, which reads a file character by character, for each iteration stores this character into a temporary variable temp. and when the value in temp is a numerical character it simply copies this value in array named s.
int main()
{
char s[10]="\0";//initialzing array to NULL's and assuming array size to be 10
int i=0,temp=0;
FILE *fp=fopen("t.txt","r"); //when file has 100-4/2
if(fp==NULL)
{
printf("\nError opening file.");
return 1;
}
while( (temp=fgetc(fp))!=EOF && i<10 ) //i<10 to not exceed array size..
{
if(temp>='0' && temp<='9')//if value in temp is a number (simple logic...)
{
s[i]=temp;
i++;
}
}
printf("%s",s);//outputs 10042
return 0;
}

c language : read file content as numbers and add them together

I have the following in a text file called: values.txt
1 4
2.5 3.76
122 10
277.543
165.4432
I am trying to read the content of this text file, and add each two pairs together and output the result ...
the output would be something like this :
1 Pair:(1, 4) = 5
2 Pair:(2.5, 3.76)= 6.26
and so on ..
I am opening the file like this
int c;
FILE myfile;
myfile= fopen("values.txt", "r");
if ( myfile == NULL ) {
printf("Cannot open TEXT file\n");
return 1;
}
double aa,bb;
while ( (c = getc(myfile) ) != EOF ) {
// HERE SHOULD I DO THE OUTPUT BUT HOW?
}
Any help is really appreciated ..
Language = C
The following code does what you expect. myfile should be declared as FILE*. fopen returns a pointer to FILE structure. If the file is very large, I would recommend reading in buffers of big size (eg: 65535 etc) and parse it char by char and convert it to float values. It reduces system call overhead which takes more time than processing text to float values.
#include <stdio.h>
#include <string.h>
main(int argc, char *argv[])
{
FILE* myfile;
myfile = fopen("values.txt", "r");
if ( myfile == NULL ) {
printf("Cannot open TEXT file\n");
return 1;
}
double aa,bb;
while (2 == fscanf(myfile, "%lf %lf", &aa, &bb)) {
printf("%lf\n", aa+bb);
}
return 0;
}
For this simple task, use double a, b;
if (fscanf(myfile, "%lf %lf", &a, &b) == 2)
printf("%f + %f = %f\n", a, b, a+b);.
looks like a homework problem but fscanf can read the string into a variable like:
int n;
fscanf (myfile,"%d",&n);
You haven't shown what you need as output for the single-value lines, but this looks like a case for fgets() and sscanf(), unless you really want the two lines with a single value to be processed as a unit.
char buffer[256];
int rownum = 0;
while (fgets(buffer, sizeof(buffer), myfile) != 0)
{
double aa, bb;
int n = sscanf(buffer, "%lf %lf", &aa, &bb);
if (n == 2)
printf("%d Pair:(%g, %g) = %g\n", ++rownum, aa, bb, aa+bb);
else if (n == 1)
printf("%d Solo:(%g) = %g\n", ++rownum, aa, aa);
else
{
printf("Failed to find any numbers in <<%s>>\n", buffer);
}
}
If you used fscanf(myfile, "%g %g", &aa, &bb), then it would read over newlines (they count as white space) looking for numbers, so it would read one number from one line, and the second from another line. This is not usually what people are after (but when it is what you need, it is extremely useful). Error recovery with fscanf() tends to be more fraught than with fgets() and sscanf().
its in c++ sorry :( i dont know c
this is a very simple logic code for simple minde :D im a begineer too, i havent tested this prog so sorry if something goes wrong but exactly
on a same principle was working my parser and it worked fine. so this is a true method. not very efficent but...
do not use this program straight away, understand it's logic this will help you alot. copying that wont give you anything
...parser tutors are so rare....
int x=0;
char ch = 'r'; //i'v used this equasion to avoid error on first ckeck of ch.
it must be filled by something when program starts.
char bigch[10];
int checknumber = 0;
float firstnumber = 0;
float secondnumber = 0;
float result=0;
void clearar(char frombigar[10], int xar) //this function gets bigch as a reference which means that eny
changes made here, will directly affect bigch itself.
ths function gets the actual length of array and puts spaces
in bigch's every element to zero out numbers. we need to clear
bigch of any previous numbers. down below you'l see why i needed this.
'xar' is the x from main function. its here to tell our cleaner the
true length of filled bigar elements.
{
for (int i=0; i
}
}
int main()
{
<------------------- //here you add file opening and reading commands
while(!myfile.eof()) //while end of txt file have not been reached
{
ch=myfile.get(); //gets each letter into ch, and make cursor one step
forward in txt file for further reading.
get() does cursor forwarding automatically
if (ch!= " ") //i used space as an indicator where one number ends
//so while space havent been reahced, read letters.
{ bigch[x] = ch; //get read letter into bigch array.
x++; //icrement bigch array step
}
else
if(ch == " ") //if space is reached that means one number has ended and
{ im trying to set a flag at that moment. it will be used further.
checknumber++; the flag is simple number. first space will set checknumber to 1
second space will set it to 2. thats all.
}
if (checknumber == 1) //if our checknumber is 1, wich means that reading
of first number is done, lets make one whole float
from that bigch array.
{ firstnumber = atof(bigch); //here we get bigch, atof (array to float) command converts
bigch array into one whole float number.
clearar(bigch,x); //here we send bigch and its element step into function where
bigch gets cleaned because we dont want some ghost numbers in it.
abviously clearar function cleans bigch int main function aswell,
not only in it's teritory. its a global cleaning :)
}
else if (checknumber ==2) //here we do the same but if flag is 2 this means that two spaces
had been passed and its time to convert bigch into secondnumber.
{ secondnumber = atof(bigch); //same method of converting array into float (it hates other
not number letters, i mean if its a number its fine. if in your text
was 'a' or 's' in that case atof will panic hehe.. )
clearar(bigch,x); //same thing, we send bigch to cleaner function to kill any numbers
it, we get one space letter ( " " ) into each element of bigch.
}
checknumber = 0; if both two numbers had been read out and converted. we need to reset
space flagger. and start counting form 0; for next pair numbers.
result = firstnumber+secondnumber; well here everything is clear.
}
}

Resources