Why is this array script not printing right results? - c

I have a textfile of numbers written in words, with spaces between like..
zero three five two one .. etc there are 3018 words in total.
This is my code:
#include <stdio.h>
int main(void)
{
int i = 0;
int d = 0;
int j = 0;
char array[9054][5];
char hi[9054];
FILE *in_file;
in_file = fopen("message.txt", "r");
while (!feof(in_file))
{
fscanf(in_file, "%s", array[i]);
i++;
}
printf(array[9049]);
while (1);
return 0;
}
so the 9049th worth in my textfile is the number three.. but when I run this script, it prints "threethreezero"instead?? i thought the fscanf ignored whitespace (spaces) so why does accept another three and zero into this string?

OP figured things out with the help of comments, so here is a cumulative fix.
#include <stdio.h>
int main(void)
{
int i = 0;
int d = 0;
int j = 0;
// Make room for the null character
char array[9054][5+1];
char hi[9054];
FILE *in_file;
in_file = fopen("message.txt", "r");
//check `fscanf()`'s return value rather than using feof()
// Limit input put with 5
while (fscanf(in_file, "%5s", array[i]) == 1);
i++;
}
// Check that code read enough input
if (i >= 9049) {
// Do not use `printf()` on uncontrolled strings that may contain %
fputs(array[9049], stdout);
} else {
puts("Oops");
}
while (1);
return 0;
}

Related

i am trying to read a file in c language the file structure is in array and i have to seperate it into array x[] and y[]

My code is to find line number and then print all element in it but it is throwing garbage value and main thing to do is to seperate front one as x and y respectively plese help me seperate x[] = [60,15,62.....] and y[] = [229,221,59,....]
Dataset is
60,229
15,221
62,59
96,120
16,97
41,290
52,206
...
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *myFile;
myFile = fopen("datasetLR1.txt", "r");
int count=0;
char c;
for (c = getc(myFile); c != EOF; c = getc(myFile)) {
if (c == '\n'){
count = count + 1;
}// Increment count if this character is newline
}
int numberArray[count*2];
int i;
if (myFile == NULL){
printf("Error Reading File\n");
exit (0);
}
for (i = 0; i < count*2; i++){
fscanf(myFile, "%d,", &numberArray[i] );
}
for (i = 0; i < count*2; i++){
printf("Number is: %d\n\n", numberArray[i]);
}
fclose(myFile);
return 0;
}
After you count the number of lines in the file with your first for loop, you should use rewind(myFile);. This puts you back to the beginning of the file. Without this, you are reading off the end of the file, which is producing the garbage values. Other than that, your code works fine.
You should also look at doing fscanf("%d,%d\n", &x, &y);, which should read off both numbers at once (and the newline) and assign them to x and y respectively. This should simplify your code significantly, however, your code works fine without it.

I'm trying to write a C program to store integers from a file into an array, but it doesn't work. Can someone help me?

It seems like I didn't quite understand how the file stream works. My text file right now contains the following integers: 1 10 5 4 2 3 -6, but I would like the program to be able to read any number of integers from the file, should it change.
Apparently I'm not even using the correct functions.
The code I have written is the following:
int main() {
printf("This program stores numbers from numeri.txt into an array.\n\n");
int a[100];
int num;
int count = 0;
FILE* numeri = fopen("numeri.txt", "r");
while (!feof(numeri)) {
num = getw(numeri);
a[count] = num;
if (fgetc(numeri) != ' ')
count++;
}
int i;
for (i = 0; i < count; i++) { printf("%d ", a[i]); }
return 0;
}
I would like it to print out the array with the stored numbers, but all I get is: 540287029 757084960 -1
Can someone help me understand what I did wrong and maybe tell me how to write this kind of code properly?
I have fixed your code based on comments. I used fscanf to read from file and limited the amount of numbers that can be stored in array by checking count < 100 and checking whether fscanf filled exactly one argument.
Also, I checked that whether file could be opened or not, just for safety. If it couldn't be opened, then just print error message and return 1.
int main() {
printf("This program stores numbers from numeri.txt into an array.\n\n");
int a[100] = {0};
int num;
int count = 0;
int i = 0;
FILE* numeri = fopen("numeri.txt", "r");
if (numeri == NULL) {
printf("Can't open file\n");
return 1;
}
while (count < 100 && fscanf(numeri, "%d", &num) == 1) {
a[count++] = num;
}
for (i = 0; i < count; i++) { printf("%d ", a[i]); }
return 0;
}

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.

show character ASCII code and number of appearance

I want to make a program which reads the text from a file and shows every character, the ASCI code of each one and the number of occurrences.
I wrote this but it doesn't show the occurrences.
#include <stdio.h>
#include <stdlib.h>
int main ()
{
FILE * pFile;
int i=0;
int j=0;
char text[j];
int ascii[256];
int occ[256];
int occurance=0;
int position;
pFile = fopen ("c:/1.in","r");
if (pFile==NULL) perror ("Error opening file");
else
{
while (!feof(pFile)) {
j++;
text[j]=getc (pFile);
ascii[j]= (int) text[j];
position=ascii[j];
occ[position]++;
}
for (i=1;i<j;i++){
occurance=position[i]
printf ("Chracter %c has ascii %d and occurs %d times \n", text[i],ascii[i],occ[occurance] );}
}
system("PAUSE");
return 0;
}
First, I don't see the point in this:
int j=0;
char text[j];
If you want to put every character in the file into an array then read the size of the file and malloc() the correct size to a pointer. But why do that anyway? If you're trying to count ever occurrence of ever character then just keep track of the possibilities.
For completeness you can use an array of 256 characters, but in reality if you're just looking at standard printable characters there should only be about 94.
This:
int main ()
{
int temp = 0, i;
int occ[256] = {0};
FILE * pFile = fopen("test.txt", "r");
if (pFile == NULL) perror("Error opening file");
else {
while (!feof(pFile)) {
temp = getc(pFile);
if((temp < 255) && (temp >= 0))
occ[temp]++;
}
}
//reads every character in the file and stores it in the array, then:
for(i = 0; i<sizeof(occ)/sizeof(int); i++){
if(occ[i] > 0)
printf(" Char %c (ASCII %#x) was seen %d times\n", i, i, occ[i]);
}
return 0;
}
will print every character, the ASCII code (in hex) and the number of times it showed.
An example input file of:
fdsafcesac3sea
yeilds an output of:
Char 3 (ASCII 0x33) was seen 1 times
Char a (ASCII 0x61) was seen 3 times
Char c (ASCII 0x63) was seen 2 times
Char d (ASCII 0x64) was seen 1 times
Char e (ASCII 0x65) was seen 2 times
Char f (ASCII 0x66) was seen 2 times
Char s (ASCII 0x73) was seen 3 times
Below simple logic works fine for me. Add file operations to get the buf.
int main()
{
char buf[] = "abcaabde";
char val[256] = {0};
int i = 0;
for (i = 0; i < sizeof(buf); i++)
{
val[buf[i]]++;
}
for (i = 0; i < 256; i++)
{
if (val[i] != 0)
{
printf("%c occured %d times\n", i, val[i]);
}
}
return 0;
}
Output is
occured 1 times
a occured 3 times
b occured 2 times
c occured 1 times
d occured 1 times
e occured 1 times

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