I've been trying to figure where I'm going wrong but I can't seem to point out where my error is exactly.
I'm trying to read from my text file, these integers
5 2 4 9 10 1 8 13 12 6 3 7 11
into an array A. To make sure it works, I was trying to print A but only getting large random numbers instead. Can someone help me see where i'm going wrong please?
int main(){
FILE* in = fopen("input.txt","r");
int A[100];
while(!feof(in)){
fscanf(in, "%s", &A);
printf("%d", A)
}
fclose(in);
return 0;
}
*this is just the main parts of the code related to the question
For all those who actually read why using feof is always wrong, the solution is something similar to the following. The code will open the filename given as the first argument to the program (or read from stdin by default):
#include <stdio.h>
enum { MAXI = 100 };
int main (int argc, char **argv) {
int i = 0, A[MAXI] = {0}; /* initialize variables */
/* read from file specified as argument 1 (or stdin, default) */
FILE *in = argc > 1 ? fopen (argv[1],"r") : stdin;
if (!in) { /* validate file opened for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
/* read each number from file or until array full */
while (i < MAXI && fscanf (in, " %d", &A[i]) == 1)
printf (" %d", A[i++]);
putchar ('\n');
if (in != stdin) fclose (in);
printf ("\n '%d' numbers read from the file.\n\n", i);
return 0;
}
Example Use/Output
Using your example values in the file dat/myints.txt results in the following:
$ ./bin/rdints dat/myints.txt
5 2 4 9 10 1 8 13 12 6 3 7 11
'13' numbers read from the file.
Related
This question already has answers here:
C read file line by line
(17 answers)
Closed 2 years ago.
120 test 123
101 test1 132
126 test2 140
150 test3 150
This is inside of a txt file. What i want to do is getting only the first number in the first line of the file and put it into an array and go to the next line then do the same thing again... for example array[0]={120} , array[1]={101}...
int j,i=1,array[20];
FILE *fp;
fp=fopen("input.txt","r");
for(i=0;i<10;i++)
fscanf(fp,"%d",&array[i]);
This is what i tried to do but i guess fscanf doesnt skip the line after getting the number... It might be a newbie question but i am stuck on that part :P
Continuing from the comment, you want to consume an entire line of input with each read, then parse the first integer from the line into your array. Using fgets() to read each line into a buffer and then parse with sscanf is a simple solution, e.g.
#include <stdio.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define MAXI 256
int main (int argc, char **argv) {
char buf[MAXC];
int array[MAXI], n = 0;
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
while (n < MAXI && fgets (buf, MAXC, fp)) /* read each line into buf */
if (sscanf (buf, "%d", &array[n]) == 1) /* parse 1st int from buf to array */
n++; /* increment counter */
if (fp != stdin) /* close file if not stdin */
fclose (fp);
for (int i = 0; i < n; i++)
printf ("array[%2d] : %d\n", i, array[i]);
}
Example Input File
$ cat dat/arr_1st_num.txt
120 test 123
101 test1 132
126 test2 140
150 test3 150
(note: blank lines or lines not beginning with an integer value are simply read and discarded and do not impact your read and storage of data)
Example Use/Output
$ ./bin/array_1st_num dat/arr_1st_num.txt
array[ 0] : 120
array[ 1] : 101
array[ 2] : 126
array[ 3] : 150
Look things over and let me know if you have further questions.
What you can do is you can scan the whole line instead as a string, then you get the first token (which is the first number) by getting the first "token" of the string using the strtok function. Lastly, we use the atoi function to convert the string number to an integer number (don't forget to include stdlib.h)
#include<stdlib.h>
int j, i=1, array[20];
FILE *fp;
fp = fopen("input.txt","r");
char currentLine[1000];
for(i=0; i<10; i++) {
fscanf(fp, "%[^\n]", currentLine);
// extract the first token
char * firstToken = strtok(currentLine, " ");
// store the firstToken (which is the number)
// to the array
array[i] = atoi(firstToken);
}
These are the errors I am running into I am doing a simple project but the main problem lies where I am trying to simply reverse the numbers of a text file for example 1234 and then rewrite to the text file to make it say 4321 I know my while loop is wrong, I was just trying a bunch of stuff to see if I can get it working but I had 0 luck getting anywhere, thank you for those of you who can help, it means a lot.
#include <stdio.h>
#include <stdlib.h>
int main()
{
//int myArray[36];
int myCount = 0;
//printf("Hello World \n");
FILE* fp = fopen("Numbers.txt", "r");
if (fp == NULL)
{
printf("Can't open file!\n");
return 1;
}
while (myCount != 0)
{
{
for(int i = myCount - 1; i >= 0; i --)
}
}
FILE* fp = fopen("Numbers.txt", "w");
fclose(fp);
return 0;
}
the expected result is that I expect the output of 1234 to be 4321 and so on and so forth with like numbers where 123456789 would be 987654321 but I currently do not have an actual output as that is what I am trying to achieve/ get, I will let those know who answer my question to let them know that it is what I need.
Alright, to read a sequence of numbers and then write them back out in reverse order, you simply need to read the values into an array, keeping track of how many you read, close the file opened for reading, reopen the file for writing, then write the values back out to the file in reverse order.
We will leave reading an unknown number of values from the file and dynamically allocating storage for another day. We will presume for now that you have less than 256 values to read (adjust as necessary). Avoid using magic-numbers in your code, so if you need a constant to size your array, #define one (or more),
#include <stdio.h>
#define MAXI 256 /* if you need a constant, #define one (or more) */
Now declare your array, declare a counter, and since you also do not hardcode filenames, pass the filename to open as the first argument to your program (or read from stdin by default if no argument is given):
int main (int argc, char **argv) {
int arr[MAXI] = {0}; /* array for storing values */
size_t n = 0; /* counter for number stored */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
Now since you have a fixed array, you cannot read more integer values that you have array elements to hold -- so always protect your array bounds when filling your array. With your file open for reading, all you need to do is read the integers from the file, and close the file after either filling all elements in your array, or reaching the end of file (EOF). Close the file you have open for reading when done:
/* protect your array bounds, and read/validate 1 int per iteration */
while (n < MAXI && fscanf (fp, "%d", &arr[n]) == 1)
n++; /* on success, increment counter */
if (fp != stdin) /* close file if not stdin */
fclose (fp);
To write the values in reverse order, simply open your file for writing (which will truncate your file). Here you can write to stdout by default if no filename was given. Then loop from your last array element (n - 1) to zero writing each element to your file in reverse order. Close the file when done, but always validate the close after writing to detect any stream errors that may occur that are not otherwise reported:
/* open file for writing (stdout by default) */
fp = argc > 1 ? fopen (argv[1], "w") : stdout;
if (!fp) { /* validate file open for writing */
perror ("file open failed");
return 1;
}
while (n--) /* write array in reverse order to file */
fprintf (fp, "%d\n", arr[n]);
if (fp != stdout) /* close file if not stdout */
if (fclose(fp) == -1) /* always validate close-after-write */
perror ("fclose-fp");
}
That's it. The full code above would be:
#include <stdio.h>
#define MAXI 256 /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
int arr[MAXI] = {0}; /* array for storing values */
size_t n = 0; /* counter for number stored */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* protect your array bounds, and read/validate 1 int per iteration */
while (n < MAXI && fscanf (fp, "%d", &arr[n]) == 1)
n++; /* on success, increment counter */
if (fp != stdin) /* close file if not stdin */
fclose (fp);
/* open file for writing (stdout by default) */
fp = argc > 1 ? fopen (argv[1], "w") : stdout;
if (!fp) { /* validate file open for writing */
perror ("file open failed");
return 1;
}
while (n--) /* write array in reverse order to file */
fprintf (fp, "%d\n", arr[n]);
if (fp != stdout) /* close file if not stdout */
if (fclose(fp) == -1) /* always validate close-after-write */
perror ("fclose-fp");
}
(note: since you didn't provide an example of your input file, a newline separated set of integers was assumed. Adjust the output format as needed)
Example Input File
$ cat dat/10intordered.txt
1
2
3
4
5
6
7
8
9
10
Example Use/Output
Reading stdin wrting to stdout (just pass your filename as 1st argument to read/write to a file),
$ ./bin/revfile < dat/10intordered.txt
10
9
8
7
6
5
4
3
2
1
Look things over and let me know if you have further questions.
Edit Removing Shortcuts & Adding Program Progress Output
With a few edits we can remove the size_t and the shortcut while(n--) loop to make things look more traditional using int and a for loop in reverse order for the second loop. We also added progress messages for both reading and writing. I used an actual file to the information is read and written back to a file to not clutter the program progress notes with the array being written in between:
#include <stdio.h>
#define MAXI 256 /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
int arr[MAXI] = {0}; /* array for storing values */
int n = 0; /* counter for number stored */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
puts ("reading file:");
/* protect your array bounds, and read/validate 1 int per iteration */
while (n < MAXI && fscanf (fp, "%d", &arr[n]) == 1) {
printf (" arr[%3d] : %d\n", n, arr[n]);
n++; /* on success, increment counter */
}
printf ("read of %d integers -- complete.\n", n);
if (fp != stdin) /* close file if not stdin */
fclose (fp);
/* open file for writing (stdout by default) */
fp = argc > 1 ? fopen (argv[1], "w") : stdout;
if (!fp) { /* validate file open for writing */
perror ("file open failed");
return 1;
}
puts ("\nwriting values to file:");
/* loop writing indexes out from n-1 to 0 */
for (int i = n-1; i >= 0; i--) {
printf (" arr[%3d] : %d\n", i, arr[i]);
fprintf (fp, "%d\n", arr[i]);
}
printf ("write of %d integers -- complete.\n", n);
if (fp != stdout) /* close file if not stdout */
if (fclose(fp) == -1) /* always validate close-after-write */
perror ("fclose-fp");
}
Example Input File
$ cat dat/10i.txt
1
2
3
4
5
6
7
8
9
10
Example Use/Output
$./bin/revfile2 dat/10i.txt
reading file:
arr[ 0] : 1
arr[ 1] : 2
arr[ 2] : 3
arr[ 3] : 4
arr[ 4] : 5
arr[ 5] : 6
arr[ 6] : 7
arr[ 7] : 8
arr[ 8] : 9
arr[ 9] : 10
read of 10 integers -- complete.
writing values to file:
arr[ 9] : 10
arr[ 8] : 9
arr[ 7] : 8
arr[ 6] : 7
arr[ 5] : 6
arr[ 4] : 5
arr[ 3] : 4
arr[ 2] : 3
arr[ 1] : 2
arr[ 0] : 1
write of 10 integers -- complete.
Updated File
$ cat dat/10i.txt
10
9
8
7
6
5
4
3
2
1
See if that may not help a bit more and let me know if you are still confused on any areas.
The Text File was writable with 1 blank line after the struct.
Is similar to:
1 111 1 Peter
22 22 2 John Lays
3 3 3 Anne Belgs
The struct is:
struct estruturaCarro {
int id, potencia, avariado;
char name[11];
} carro;
I have write the data to the text File:
fprintf(fp, "%-2d %-3d %-1d %-10s \n\n", carro.id, carro.potencia, carro.avariado, carro.name);
I read the file data this way, but I'm sure it's not the best way:
while(true){
int result = fscanf(fp, "%d %d %d %10[^\n]", &carro.id, &carro.potencia, &carro.avariado, &carro.name);
if(result==4){
printf("%-2d %-3d %-1d % -s\n", carro.id, carro.potencia, carro.avariado, carro.name);
}else break;
}
How can I read the text file, saving the data struct, without reading the blank lines?
If I want to validate the values read (ID = xx, potencia = xxx, avariado = x, name = 10 characters), is it better, before or after filling the array of struct?The format of each line of the file is:xx xxx x aaaaaaaaaa (x = digits, a = characters)For example, if one of the lines is
9 123 4 Error 1st value
stop reading the file (informing the user), because the line should be:
9 123 4 Error 1st value (one space was missing after 9) - or because NAME has more than 10 characters.
You don't show how true is set in while(true), but it must be based on the return of fscanf in the way you are approaching it. You must test three cases:
fscanf return is EOF, read done, true should be set to FALSE to break loop;
fscanf return less than 4, matching or input failure, no guarantee this occurred due to an empty line; and
fscanf return is equal to 4, good input.
Unless you are checking all three, you cannot cover all cases for fscanf and further, if there is any additional or extraneous character in your input file, your formatted read will fail.
That is why a better option is to read each line into a buffer with fgets and then parse the information you need from the buffer itself with sscanf. This provides the benefit of allowing separate validation of (1) the read; and (2) the parse of information. Further, since you are consuming a line-at-a-time, there is no uncertainty on what remains in the input stream and a failure in parsing any one line does not prevent a successful read of the remainder.
A short implementation with fgets() and sscanf() reading each struct into an array-of-struct, you can do something similar to the following:
#include <stdio.h>
#define MAXN 11 /* if you need a constant, #define one (or more) */
#define MAXC 1024 /* (don't skimp on buffer size) */
typedef struct { /* use a simple typedef */
int id, potencia, avariado;
char name[MAXN];
} carro_t;
int main (int argc, char **argv) {
char buf[MAXC]; /* buffer to read line */
carro_t carro[MAXN] = {{ .id = 0 }}; /* array of struct */
size_t ndx = 0; /* array index */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
while (ndx < MAXN && fgets (buf, MAXC, fp)) { /* read each line */
carro_t tmp = { .id = 0 }; /* temp struct */
if (*buf == '\n') /* if line empty */
continue; /* get next line */
if (sscanf (buf, "%d %d %d %10[^\n]", /* separate/validate */
&tmp.id, &tmp.potencia, &tmp.avariado, tmp.name) == 4)
carro[ndx++] = tmp; /* add to array of struct */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
for (size_t i = 0; i < ndx; i++)
printf ("%3d %3d %3d %s\n",
carro[i].id, carro[i].potencia, carro[i].avariado, carro[i].name);
return 0;
}
(note: the filename is provide as the first argument to the program, or if no filename is provided, read from stdin by default)
While with your particular data file, there is no reason you cannot use fscanf, it is fragile and one character too many (like "Anne Belgss") will cause it to break. A fscanf implementation removing the true and simply looping as you have could be:
for (;;) {
carro_t tmp = { .id = 0 };
if (fscanf (fp, "%d %d %d %10[^\n]", /* separate/validate */
&tmp.id, &tmp.potencia, &tmp.avariado, tmp.name) == 4)
carro[ndx++] = tmp; /* add to array of struct */
else
break;
}
Either way, you will produce the same output with "this" input file, e.g.
Example Use/Output
$ ./bin/readwblanks ~/tmpd/file
1 111 1 Peter
22 22 2 John Lays
3 3 3 Anne Belgs
just use simple reading way is ok,like this.
while(fscanf(fp,"%d %d %d %s",&carro.id,&carro.potencia,&carro.avariado,carro.name)!=EOF)
printf("%d %d %d %s\n",carro.id,carro.potencia,carro.avariado,carro.name);
result is like this
enter image description here
I need to find the degree of inversion for a set of numbers in a file.
I read input from a .txt file in the form:
SET 1: -3 1 2 0 4
SET 2: 0 1 2 3 4 5
SET 4: 29 39 0 1 3
I do not know how to separate the input (the set and its numbers). I thought of putting them in a struct but so far it's not working.
The degree of inversion = number of numbers that are smaller than their index value. For example, in SET 2, the degree of inversion is 0.
You need to post code on where you are stuck; that is the best way to get help.
Anyway, here is some rough code to help you identify where your issues may be. I have kept it simple to allow you to follow through with how vanilla C does I/O.
#include <stdio.h> /* snprinf, fprintf fgets, fopen, sscanf */
int main(void)
{
char line_buffer[64];
FILE* infile = fopen("yourfile.txt", "r"); /* open file for reading */
while(fgets(line_buffer, 64, infile) != NULL)
{
char set_name[8]; /* construct a string w/ the set number */
snprintf(set_name, 8, "SET %c:", *(line_buffer+4)); /* no. is 5th char */
fprintf(stdout, "%s ", set_name); /* fprintf w/ stdout = printf */
int set[8];
int ind = 0;
for(int i=7; line_buffer[i]!='\0';) /* start from first number and end */
{ /* when string ends, denoted by the '\0' sentinel */
int n; /* using pointer arithmetric, read in and store num & consume */
sscanf(line_buffer+i, "%d %n", set+ind, &n); /* adjacent whitespace */
i += n; /* n from sscanf tells how many chars are read in */
fprintf(stdout, "%d ", set[ind]);
ind +=1;
}
fprintf(stdout, "\n");
}
return 0;
}
I'm currently working on a program that simulates various CPU scheduling methods. Currently I have the program asking for input:
printf("Enter type of CPU scheduling algorithm (SJF, RR, PR_noPREMP, PR_withPREMP): ");
scanf("%s", typeOf);
printf("Enter number of processes: ");
scanf("%d", &numPro);
struct processStruct structs[numPro];
int burstTimes[numPro];
for (i = 0; i < numPro; i++) {
printf("Enter process number: ");
scanf("%d", &structs[i].pNum);
printf("Enter arrival time: ");
scanf("%d", &structs[i].arTime);
printf("Enter CPU burst time: ");
scanf("%d", &structs[i].cpuBur);
printf("Enter priority: ");
scanf("%d", &structs[i].prio);
}
In addition to the two variables typeOf (an int) and numPro (a char array) I am also using a data structure.
Here is the data structure that is holding the various parameters:
struct processStruct {
int pNum;
int arTime;
int cpuBur;
int prio;
int waitTim;
};
Instead of manual input I could like to use a text file with the same information as input for the program. The text file would look something like this:
SJF
4
1 0 6 1
2 0 8 1
3 0 7 1
4 0 3 1
First line is the name of the scheduling algorithm.
Second line is the number of processes.
The following lines consists of information for each process. So 1 0 6 1 = Process = 1, 0 = Arrival Time, 6 = CPU burst time, 1 = Priority
I unfortunately have little experience using text file input with C. Does anyone have ideas about how I could read in the data from the text file into the variables and data structure?
Thank you
Edit: One of the issues I am having is that the data is not the same for each line. If it was just the rows of 4 numbers then it would be relatively easy. I need the program to read the first line into a char array (string), the second into the numPro variable then the subsequent lines into multiple instances of the data structure (one for each process).
The file can be read fairly simply with fscanf() because everything except the first line identifier is a number. But you do need to check the validity of what is read from the file. I have just used exit(1) on error for illustration, it could be more sophisticated than that (for example an error message).
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
struct processStruct {
int pNum;
int arTime;
int cpuBur;
int prio;
int waitTim;
};
struct processStruct structs[MAX];
int main(int argc, char** args)
{
FILE *fil;
char typeOf[4];
int numPro, i;
if ((fil = fopen("myfile.txt", "rt")) == NULL)
exit(1);
if(fscanf(fil, "%4s", typeOf) != 1)
exit(1);
if(fscanf(fil, "%d", &numPro) != 1)
exit(1);
if(numPro > MAX)
exit(1);
for(i=0; i<numPro; i++) {
if(fscanf(fil, "%d%d%d%d", &structs[i].pNum, &structs[i].arTime,
&structs[i].cpuBur, &structs[i].prio) != 4)
exit(1);
}
fclose(fil);
// test the result
printf("Type: %s\n", typeOf);
printf("Num: %d\n", numPro);
for(i=0; i<numPro; i++) {
printf("%d %d %d %d\n", structs[i].pNum, structs[i].arTime,
structs[i].cpuBur, structs[i].prio);
}
return 0;
}
Program output:
Type: SJF
Num: 4
1 0 6 1
2 0 8 1
3 0 7 1
4 0 3 1
You will want to use fscanf and fprintf instead of scanf and printf to do I/O from/to files instead of standard input/output.
These are widely documented. You will use FILE * variables and fopen & fclose. You can even use stdin, stdout, and stderr as handles for the console.
The best way to read lines in a file with C is to use the getline() function. It is much more reliable than scanf() and can allocate the needed memory automagically.
Here is the code I suggest:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv)
{
FILE *inputfile;
if (argc < 2)
{
fprintf (stderr, "error: missing file name in the arguments\n");
exit (EXIT_FAILURE);
}
inputfile = fopen (argv[1], "r");
if (!inputfile)
{
perror ("myprogram");
exit (EXIT_FAILURE);
}
/* Getting first line */
char *line = NULL;
size_t line_size = 0;
if (!getline(&line, &line_size, inputfile))
{
fprintf (stderr, "error: failed to read first line\n");
exit (EXIT_FAILURE);
}
/* Getting the size of the matrix */
unsigned int size; /* Size of the matrix */
if (sscanf (line, "%zd", &size) != 1)
{
fprintf (stderr, "error: first line has wrong format\n");
exit (EXIT_FAILURE);
}
/* Getting the content of the matrix */
int matrix[size][size];
for (unsigned int i = 0; i < size; i++)
{
if (!getline (&line, &line_size, inputfile))
{
fprintf (stderr, "error: input file has wrong format\n");
exit (EXIT_FAILURE);
}
/* Copying the items of the line to the matrix */
char *ptr = line;
for (unsigned j = 0; j < size; j++)
{
matrix[i][j] = atoi(strtok(ptr, " "));
ptr = NULL;
}
}
free(line);
return EXIT_SUCCESS;
}
Beware, I didn't tried this code... So, if something is not working properly, I'll fix it.