I am trying to read the ints from a CSV file into a 2D-Array.
Here is my code...
FILE* fp = fopen(argv[1], "r");
int counter = 0;
char line[50];
while (fgets(line, 50, fp)) {
counter++;
}
int arry[counter - 1][4];
NUM_ROWS = counter -1;
counter = 0;
//Iterate File Again to Populate 2D Array of PID, Arrival Time, Burst Time, Priority
//File in Format: #,#,#,#
rewind(fp);
//Skip First Line of Var Names
fgets(line, 50, fp);
while(fgets(line, 50, fp)) {
sscanf(line, "%d%d%d%d", &arry[counter][0], &arry[counter][1], &arry[counter][2], &arry[counter][3]);
counter++;
}
However, sscanf() is not reading the line into the array. I am unsure why this is not working
Edit: Here is a picture of the file.
You need to have the scanf format string which reflects the format of the scanned line.
Always check the result of scanf
Example:
int main(void)
{
char line[] = "34543,78765,34566,35456";
int arry[1][4];
int counter = 0;
int result = sscanf(line, "%d,%d,%d,%d", &arry[counter][0], &arry[counter][1], &arry[counter][2], &arry[counter][3]);
printf("result = %d\n", result);
printf("CSV line = `%s`\n", line);
printf("data read: %d, %d, %d, %d\n", arry[counter][0], arry[counter][1], arry[counter][2], arry[counter][3]);
}
https://godbolt.org/z/zs5Y8ff8h
Related
How should I read a specific number of lines in C? Any tips, since I can't seem to find a relevant thread.
I would like to read N lines from a file and N would be argument given by the user.
Up until this point I have been reading files this way: (line by line until NULL)
int main(void) {
char line[50];
FILE *file;
file= fopen("filename.txt", "r");
printf("File includes:\n");
while (fgets(line, 50, file) != NULL) {
printf("%s", line);
}
fclose(file);
return(0);
}
If N is given by the user, you could just make your loop count up to N:
for (int i = 0; i < N && fgets(line, sizeof line, file); ++i) {
fputs(line, stdout);
}
I need help to read the numbers of a .txt file and put them in an array. But only from the second line onwards. I'm stuck and don't know where to go from the code that i built.
Example of the .txt file:
10 20
45000000
48000000
56000000
#define MAX 50
int main (void){
FILE *file;
int primNum;
int secNum;
int listOfNumers[50];
int numberOfLines = MAX;
int i = 0;
file = fopen("file.txt", "rt");
if (file == NULL)
{
printf("Error\n");
return 1;
}
fscanf(file, "%d %d\n", &primNum, &secNum);
printf("\n1st Number: %d",primNum);
printf("\n2nd Number: %d",secNum);
printf("List of Numbers");
for(i=0;i<numberOfLines;i++){
//Count the number from the second line onwards
}
fclose(file);
return 0;
}
You just need a loop to keep reading ints from file and populate the listOfNumers array until reading an int fails.
Since you don't know how many ints there are in the file, you could also allocate the memory dynamically. Example:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE* file = fopen("file.txt", "rt");
if(file == NULL) {
perror("file.txt");
return 1;
}
int primNum;
int secNum;
if(fscanf(file, "%d %d", &primNum, &secNum) != 2) {
fprintf(stderr, "failed reading primNum and secNum\n");
return 1;
}
unsigned numberOfLines = 0;
// allocate space for one `int`
int* listOfNumers = malloc((numberOfLines + 1) * sizeof *listOfNumers);
// the above could just be:
// int* listOfNumers = malloc(sizeof *listOfNumers);
while(fscanf(file, "%d", listOfNumers + numberOfLines) == 1) {
++numberOfLines;
// increase the allocated space by the sizeof 1 int
int* np = realloc(listOfNumers, (numberOfLines + 1) * sizeof *np);
if(np == NULL) break; // if allocating more space failed, break out
listOfNumers = np; // save the new pointer
}
fclose(file);
puts("List of Numbers:");
for(unsigned i = 0; i < numberOfLines; ++i) {
printf("%d\n", listOfNumers[i]);
}
free(listOfNumers); // free the dynamically allocated space
}
There are a few ways to approach this; if you know the size of the first line, you should be able to use fseek to move the position of the file than use getline to get each line of the file:
int fseek(FILE *stream, long offset, int whence);
The whence parameter can be:
SEEK_SET : the Beginning
SEEK_CUR : the current position
SEEK_END : the End
The other option would to encapsulate the entire file read in a while loop:
char *line = NULL;
size_t linecap = 0;
ssize_t linelen;
int counter = 0;
while((linelen = getline(&line, &linecap, file)) != -1){
if counter == 0{
sscanf(line, "%d %d\n", &primNum, &secNum);
}else{
//Process your line
}
counter++; //This would give you your total line length
}
I am trying to read the ints from a CSV file into a 2D-Array.
Here is my code...
FILE* fp = fopen(argv[1], "r");
int counter = 0;
char line[50];
while (fgets(line, 50, fp)) {
counter++;
}
int arry[counter - 1][4];
NUM_ROWS = counter -1;
counter = 0;
//Iterate File Again to Populate 2D Array of PID, Arrival Time, Burst Time, Priority
//File in Format: #,#,#,#
rewind(fp);
//Skip First Line of Var Names
fgets(line, 50, fp);
while(fgets(line, 50, fp)) {
sscanf(line, "%d%d%d%d", &arry[counter][0], &arry[counter][1], &arry[counter][2], &arry[counter][3]);
counter++;
}
However, sscanf() is not reading the line into the array. I am unsure why this is not working
Edit: Here is a picture of the file.
You need to have the scanf format string which reflects the format of the scanned line.
Always check the result of scanf
Example:
int main(void)
{
char line[] = "34543,78765,34566,35456";
int arry[1][4];
int counter = 0;
int result = sscanf(line, "%d,%d,%d,%d", &arry[counter][0], &arry[counter][1], &arry[counter][2], &arry[counter][3]);
printf("result = %d\n", result);
printf("CSV line = `%s`\n", line);
printf("data read: %d, %d, %d, %d\n", arry[counter][0], arry[counter][1], arry[counter][2], arry[counter][3]);
}
https://godbolt.org/z/zs5Y8ff8h
I need to scan values from .txt to a structure so I can work further on with my program. I've been trying various methods from the thread and this is the closes I got to a successful build.
I can NOT get the values to be printed out so I can test if they scanned correctly before working my way further into the program.
I have different values in struct:
struct knyga
{
char vardas[10];
char pavadinimas[50];
int metai;
double kaina;
};
and this is my reading function:
void Skaitymas(struct knyga arr_knyga[]){
FILE *fp;
fp = fopen("duomenys.txt", "r");
int skaicius;
int txt;
txt = fgetc(fp);
while((txt = fgetc(fp)) != EOF){
if(txt == '\n') skaicius++;
txt = fgetc(fp);
}
printf("%d", skaicius);
fp = fopen("duomenys.txt", "r");
for(int i = 0; i < skaicius; i++){
fscanf(fp, "%s %s %d %lf", arr_knyga[i].vardas, arr_knyga[i].pavadinimas, &arr_knyga[i].metai, &arr_knyga[i].kaina);
}
fclose(fp);
}
EDIT:
This is the content of my text file:
Onute Knyga 1999 12.12
Petras Knygute 2001 9.99
EDIT 2:
my main function:
int main() {
struct knyga arr_knyga[10];
Skaitymas(arr_knyga);
return 0;
}
You call txt = fgetc(fp); too often. The two occurrences of this line must be removed.
Especially in the loop you have one call to fgetc that is checked for '\n' and a second call that is not checked, so there is a 50%/50% chance that a '\n' is not counted.
You forgot to initialize the counter variable.
The counting would be correct with this version:
void Skaitymas(struct knyga arr_knyga[]){
FILE *fp;
fp = fopen("duomenys.txt", "r");
int skaicius = 0;
int txt;
while((txt = fgetc(fp)) != EOF){
if(txt == '\n') skaicius++;
}
printf("%d", skaicius);
fclose(fp);
}
But it would be better to omit the line-counting and detect the end-of-file condition in the fscanf loop.
void Skaitymas(struct knyga arr_knyga[]){
FILE *fp;
fp = fopen("duomenys.txt", "r");
int skaicius = 0;
int rc;
while(1)
{
rc = fscanf(fp, "%s %s %d %lf", arr_knyga[skaicius].vardas, arr_knyga[skaicius].pavadinimas, &arr_knyga[skaicius].metai, &arr_knyga[skaicius].kaina);
if(rc == 4)
{
skaicius++;
}
else
{
break;
}
}
if(!feof(fp))
{
fprintf(stderr, "error reading file or wrong data after line %d\n", skaicius);
}
else
{
printf("%d", skaicius);
}
fclose(fp);
}
Im trying to read a text file with inputs in the above format. Im able to read each line with this code:
FILE *file = fopen(argv[1], "r");
...
char * line = NULL;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, file)) != -1)
so that "line" is equal to each line in the file and if i output what is read for ex: i get the first output as "1 2 3 4 5 6 7 8 9". How can i store these numbers to a 2d array ?. how can i split at each space and get the number only ?
Sample using sscanf
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
int numbers[9][9];
FILE *file = fopen(argv[1], "r");
char * line = NULL;
size_t len = 0;
ssize_t read;
int rows = 0;
while ((read = getline(&line, &len, file)) != -1){
int *a = numbers[rows];
if(9 != sscanf(line, "%d%d%d%d%d%d%d%d%d", a, a+1, a+2,a+3,a+4,a+5,a+6,a+7,a+8)){
fprintf(stderr, "%s invalid format at input file\n", line);
return EXIT_FAILURE;
}
if(++rows == 9)
break;
}
fclose(file);
free(line);
//check print
for(int r = 0; r < 9; ++r){
for(int c = 0; c < 9; ++c)
printf("%d ", numbers[r][c]);
puts("");
}
}
A string is an array, so you just want to copy the contents of the string, character by character to another array, unless the character is not alphanumeric.
You could do some checks first to see how many alphanumeric characters are in the current string and then grab that amount of memory for your new array.