I do have a txt file which looks like this
10
41 220 166 29 151 47 170 60 234 49
How can I read only the numbers from the second row into an array in C?
int nr_of_values = 0;
int* myArray = 0;
FILE *file;
file = fopen("hist.txt", "r+");
if (file == NULL)
{
printf("ERROR Opening File!");
exit(1);
}
else {
fscanf(file, "%d", &nr_of_values);
myArray = new int[nr_of_values];
// push values from second row to this array
}
How can I read only the numbers from the second row into an array in C?
Ignore the first line by reading and discarding it.
You could use something like that:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char const *filename = "test.txt";
FILE *input_file = fopen(filename, "r");
if (!input_file) {
fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
return EXIT_FAILURE;
}
int ch; // ignore first line:
while ((ch = fgetc(input_file)) != EOF && ch != '\n');
int value;
int *numbers = NULL;
size_t num_numbers = 0;
while (fscanf(input_file, "%d", &value) == 1) {
int *new_numbers = realloc(numbers, (num_numbers + 1) * sizeof(*new_numbers));
if (!new_numbers) {
fputs("Out of memory :(\n\n", stderr);
free(numbers);
return EXIT_FAILURE;
}
numbers = new_numbers;
numbers[num_numbers++] = value;
}
fclose(input_file);
for (size_t i = 0; i < num_numbers; ++i)
printf("%d ", numbers[i]);
putchar('\n');
free(numbers);
}
Related
I need to load strings from file into a struct array.
CORRECT OUTPUT:
4
Sarajevo,345123
Tuzla,123456
Mostar,101010
Banja Luka,234987
MY OUTPUT:
1
Sarajevo 345123
Tuzla 123456
Mostar 101010
Banja Luka 234987,544366964
Code:
#include <stdio.h>
#include <string.h>
struct City {
char name[31];
int number_of_citizen;
};
int load(struct City cities[100], int n) {
FILE *fp = fopen("cities.txt", "r");
int i = 0;
while (fscanf(fp, "%[^,]s %d\n", cities[i].name, &cities[i].number_of_citizen)) {
i++;
if (i == n)break;
if (feof(fp))break;
}
fclose(fp);
return i;
}
int main() {
int i, number_of_cities;
struct City cities[10];
FILE* fp = fopen("cities.txt", "w");
fputs("Sarajevo 345123", fp); fputc(10, fp);
fputs("Tuzla 123456", fp); fputc(10, fp);
fputs("Mostar 101010", fp); fputc(10, fp);
fputs("Banja Luka 234987", fp);
fclose(fp);
number_of_cities = load(cities, 10);
printf("%d\n", number_of_cities);
for (i = 0; i < number_of_cities; i++)
printf("%s,%d\n", cities[i].name, cities[i].number_of_citizen);
return 0;
}
Could you explain me how to fix this? Why my program only loaded 1 city?
The fscanf() conversion string is incorrect: instead of "%[^,]s %d\n" you should use:
while (i < n && fscanf(fp, "%30[^,],%d",
cities[i].name,
&cities[i].number_of_citizen) == 2) {
i++;
}
Or better:
#include <errno.h>
#include <stdio.h>
#include <string.h>
int load(struct City cities[], int n) {
char buf[200];
int i = 0;
char ch[2];
FILE *fp = fopen("cities.txt", "r");
if (fp == NULL) {
fprintf(stderr, "cannot open %s: %s\n", "cities.txt",
strerror(errno));
return -1;
}
while (i < n && fgets(buf, sizeof buf, fp)) {
if (sscanf(buf, "%30[^,],%d%1[\n]",
cities[i].name,
&cities[i].number_of_citizen, ch) == 3) {
i++;
} else {
fprintf(stderr, "invalid record: %s\n", buf);
}
}
fclose(fp);
return i;
}
Also change your main function to output commas between the city names and population counts:
int main() {
int i, number_of_cities;
struct City cities[10];
FILE *fp = fopen("cities.txt", "w");
if (fp) {
fputs("Sarajevo,345123\n", fp);
fputs("Tuzla,123456\n", fp);
fputs("Mostar,101010\n", fp);
fputs("Banja Luka,234987\n", fp);
fclose(fp);
}
number_of_cities = load(cities, 10);
printf("%d\n", number_of_cities);
for (i = 0; i < number_of_cities; i++)
printf("%s,%d\n", cities[i].name, cities[i].number_of_citizen);
return 0;
}
EDIT: since there are no commas in the database file, you must use a different parsing approach:
#include <errno.h>
#include <stdio.h>
#include <string.h>
int load(struct City cities[], int n) {
char buf[200];
int i = 0;
FILE *fp = fopen("cities.txt", "r");
if (fp == NULL) {
fprintf(stderr, "cannot open %s: %s\n", "cities.txt",
strerror(errno));
return -1;
}
while (i < n && fgets(buf, sizeof buf, fp)) {
/* locate the last space */
char *p = strrchr(buf, ' ');
if (p != NULL) {
/* convert it to a comma */
*p = ',';
/* convert the modified line */
if (sscanf(buf, "%30[^,],%d",
cities[i].name,
&cities[i].number_of_citizen) == 2) {
i++;
continue;
}
}
fprintf(stderr, "invalid record: %s", buf);
}
fclose(fp);
return i;
}
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 data from a csv file input below:
0, 0
5, 0
7, 0
This input is supposed to be x and y coordinates where x= 0 and y =0 and x=5 and y=5 and so on....
What i have tried
I am trying to print the numbers and then store each one. I can't store them or print them correctly as I am new to C and I am finding it difficult
Required output:
x:0 y:0
x:5 y:0
x:7 y:0
This is my code below:
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <string.h>
int main()
{
FILE* fp = fopen("points.csv", "r");
if (!fp)
printf("Can't open file\n");
else {
char buffer[1024];
int row = 0;
int column = 0;
int distance;
while (fgets(buffer,
1024, fp)) {
column = 0;
row++;
if (row == 1)
continue;
// Splitting the data
char* value = strtok(buffer, ",");
while (value) {
// Column 1
if (column == 0) {
printf("x:");
}
// Column 2
if (column == 1) {
printf("\ty:");
}
printf("%s", value);
value = strtok(NULL, ", ");
column++;
}
// distance = ((x2-x1) *(x2-x1)) + ((y2-y1) * (y2-y1));
printf("\n");
}
fclose(fp);
}
return 0;
}
Since your file contains only two columns, you can write it this way using sscanf():
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp = fopen("file", "r");
if (!fp) {
fprintf(stderr, "Can't open file\n");
return 1;
}
char line[1024];
int x, y;
while (fgets(line, sizeof line, fp)) {
line[strcspn(line, "\n")] = '\0'; // Replace '\n' read by fgets() by '\0'
if (sscanf(line, "%d, %d", &x, &y) != 2) {
fprintf(stderr, "Bad line\n");
}
printf("x:%d\ty:%d\n", x, y);
}
fclose(fp);
}
Struggling to move tokens to a 2D array .
The idea is that I am reading a file with multiple lines , get the number of lines and then based on that create a 2D array to use memory wisely(I dont want to create a 100 x 3 array for no reason).
I think I got the 2D array initialized in a separate funtion but when I try to enter data read from strtok() , I am getting error :
error: 'arr' undeclared (first use in this function)
strcpy(&arr[s2][c2],token);
Here is my code :
#include <stdio.h>
#include <string.h>
int ch, lines;
int no_of_lines(char* fp)
{
while(!feof(fp)) {
ch = fgetc(fp);
if(ch == '\n') {
lines++;
}
}
lines++;
return lines;
}
void declare_space_array(int size)
{
char* arr = (char*)malloc(size * 3 * sizeof(char));
return;
}
int main(void)
{
int c2 = 0;
int s2 = 0;
int len;
// char data[10][4];
static const char filename[] = "C:\\Users\\PC\\Documents\\Assignments\\stringops\\test.txt";
FILE* file = fopen(filename, "r");
no_of_lines(file);
printf("No of lines in file = %d", lines);
printf("\n");
// Closing file because it was read once till the end of file
fclose(file);
// Opening file again to read for parsing
file = fopen(filename, "r");
declare_space_array(lines);
char* token;
if(file != NULL) {
char line[128];
while(fgets(line, sizeof line, file) != NULL)
{
len = strlen(line);
printf("%d %s", len - 1, line);
const char s = ",";
token = strtok(line, ",");
while(token != NULL) {
strcpy(arr[s2][c2], token);
// printf( "%s\n", token );
token = strtok(NULL, ",");
c2++;
}
s2++;
}
fclose(file);
} else {
perror(filename); /* why didn't the file open? */
}
for(r1 = 0; r1 < lines; r1++) {
for(c1 = 0; c1 < 3; c1++) {
printf("%s", &arr[r1][c1]);
}
}
return 0;
}
file is something like this:
A1,B1,C1
A2,B2,C2
A3,B3,C3
EXPECTED OUTPUT TO SOMETHIGN LIKE THIS:
A1
B1
C1
A2
B2
C2
A3
B3
C3
After discussion in chat, etc, you could end up with code like this. This uses a global variable arr that's a pointer to an array of arrays of 3 char * values.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int lines = 0;
static char *(*arr)[3] = 0; // global definition.
static int no_of_lines(FILE *fp)
{
lines = 0;
int ch;
while ((ch = fgetc(fp)) != EOF)
{
if (ch == '\n')
lines++;
}
return ++lines; // Allow for last line possibly not having a newline
}
static void declare_space_array(int size)
{
arr = calloc(size, 3 * sizeof(char *)); // zeroed memory allocation
if (arr == 0)
{
fprintf(stderr, "Failed to allocate memory\n");
exit(1);
}
}
int main(void)
{
int c2 = 0;
int s2 = 0;
int len;
// char data[10][4];
// static const char filename[] = "C:\\Users\\PC\\Documents\\Assignments\\stringops\\test.txt";
const char *filename = "data";
FILE *file = fopen(filename, "r");
if (file == 0)
{
fprintf(stderr, "Failed to open file '%s' for reading\n", filename);
exit(1);
}
no_of_lines(file);
printf("No of lines in file = %d\n", lines);
rewind(file);
declare_space_array(lines);
const char delims[] = ",\n";
char line[128];
while (fgets(line, sizeof line, file) != NULL)
{
char *token;
c2 = 0;
len = strlen(line);
printf("%d [%.*s]\n", len - 1, len - 1, line);
token = strtok(line, delims);
while (token != NULL)
{
arr[s2][c2] = strdup(token); // copy token (from strtok) into newly allocated string.
token = strtok(NULL, delims);
c2++;
}
s2++;
}
fclose(file);
for (int r1 = 0; r1 < lines; r1++)
{
if (arr[r1][0] != 0)
{
for (int c1 = 0; c1 < 3; c1++)
printf(" %-10s", arr[r1][c1]);
putchar('\n');
}
}
return 0;
}
It doesn't release the memory that's allocated — I got lazy.
Sample data (note that the names are longer than 2 characters and are of variable length):
server1,Phoenix,Windows
server2,Dallas,Linux
server-99,London,z/OS
Sample output:
No of lines in file = 4
23 [server1,Phoenix,Windows]
20 [server2,Dallas,Linux]
21 [server-99,London,z/OS]
server1 Phoenix Windows
server2 Dallas Linux
server-99 London z/OS
The 'number of lines in file = 4' allows for the possibility that there isn't a newline at the end of the last line. The code in the printing loop allows for the possibility that there was a newline at the end and therefore the count is an over-estimate. It would spot a memory allocation from strdup() as long as the failure was on the first field of a line. It might crash if it was the second or third field that was not successfully copied.
I want to read a file which looks like this:
Name=José, Age=21
Name=Antonio, Age=26
Name=Maria, Age=24
My problem is how can i read the names and ages from different positions and different lines and put in an array names[size] and the same thing for the ages ages[size].
I have this at the moment:
#include <stdio.h>
#define size 100
int main()
{
char ch = 0;
int i = 0;
char names[size];
char ages[size];
FILE *fp1;
fp1 = fopen("data.txt", "r");
if(fp1 == NULL)
{
printf("Error!");
return 1;
}
while((ch=fgetc(fp1)) != '=');
while((ch=fgetc(fp1)) != ',')
{
fscanf(fp1, "%s", names);
i++;
}
fclose(fp1);
printf("Names = %s", names);
return 0;
}
Can anyone explain me what is the best way to do it?
you need 2D-Array. E.g names[number of record][max length size + 1]
a way sample like this
#include <stdio.h>
#define size 100
int main(void){
int i = 0;
char names[size][128];
char ages[size][4];
FILE *fp1;
fp1 = fopen("data.txt", "r");
if(fp1 == NULL){
printf("Error!\n");
return 1;
}
while(i < size && 2 == fscanf(fp1, "Name=%127[^,], Age=%3[0-9]\n", names[i], ages[i])){
i++;
}
fclose(fp1);
int n = i;
for(i = 0; i < n; ++i)
printf("Names = %s, Ages = %s\n", names[i], ages[i]);
return 0;
}