C - Mixed Text File Data > To Different Arrays (Int and String) - c

I have just an ordinary "project.txt" file with this data:
Programming 10 3 4 5 4 3 2 4 5 2 3
Mathematics 8 3 3 4 5 3 2 2 3
Physics 6 3 4 5 3 4 5
Design 6 5 4 5 3 2 4
Logistics 8 3 4 5 3 1 1 2 3
Need to open this file, read and write all this data to arrays.
I need to somehow divide String and Integers from each other.
* NO NEED FOR IT RIGHT NOW, but later I will need to write text and numbers to different files. ***NO NEED TO DO THIS NOW*
Just need to do it with 2 different int and char arrays, but I am sitting for few hours and can't find normal explanation of how to divide this string from other things.
Here is my code, can anybody help me?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *fp;
fp = fopen("C:\\Project\\project.txt", "r");
char arrayWords[140];
int i;
if(fp == NULL){
printf("Can't Read The File!");
exit(0);
}
for (i = 0; i < 140; i++){
fscanf(fp, "%s,", &arrayWords[i]);
}
for (i = 0; i < 140; i++){
printf("Number is: %s\n\n", &arrayWords[i]);
}
fclose(fp);
return 0;
}
This is the output I get, it is really confusing (Some part of it)...
Number is: P13454324523M833453223P6345345D6545324L834531123
Number is: 13454324523M833453223P6345345D6545324L834531123
Number is: 3454324523M833453223P6345345D6545324L834531123
Number is: 454324523M833453223P6345345D6545324L834531123
Number is: 54324523M833453223P6345345D6545324L834531123
Number is: 4324523M833453223P6345345D6545324L834531123
Number is: 324523M833453223P6345345D6545324L834531123
Number is: 24523M833453223P6345345D6545324L834531123
Number is: 4523M833453223P6345345D6545324L834531123
Number is: 523M833453223P6345345D6545324L834531123
Number is: 23M833453223P6345345D6545324L834531123
Number is: 3M833453223P6345345D6545324L834531123
Number is: M833453223P6345345D6545324L834531123
Number is: 833453223P6345345D6545324L834531123
Number is: 33453223P6345345D6545324L834531123
Number is: 3453223P6345345D6545324L834531123
Number is: 453223P6345345D6545324L834531123
Number is: 53223P6345345D6545324L834531123
Number is: 3223P6345345D6545324L834531123
Number is: 223P6345345D6545324L834531123
Number is: 23P6345345D6545324L834531123
Number is: 3P6345345D6545324L834531123
Number is: P6345345D6545324L834531123
Number is: 6345345D6545324L834531123
Number is: 345345D6545324L834531123
Number is: 45345D6545324L834531123
Number is: 5345D6545324L834531123
Number is: 345D6545324L834531123
Number is: 45D6545324L834531123
Number is: 5D6545324L834531123
Think problem is in pointers, but don't know, I am kind of a beginner and can't find any problems.
Thanks to everyone

It's easy to parse these lists of space-separated numbers using the strtol() function. This is a good solution because it handily sets a pointer to the next block of whitespace/non-number after the number it just converted. If there's no number to convert, it just sends back the original pointer. So the code tests for this to know when it's complete.
EDIT: Updated to handle name too.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *number_str = "SomeWords 19 9 6 2 22 1 0 -4";
char *ptr;
char *next_number;
int numbers[1000];
int number_count = 0;
char name[100];
next_number = number_str;
// Copy off the name
ptr = strchr(number_str, ' ');
if (ptr != NULL)
{
strncpy(name, number_str, ptr-number_str); // TODO - check bounds of name[]
name[ptr-number_str] = '\0';
// Point to the first number
next_number = ptr+1;
printf("Stored name [%s]\n", name);
}
// Then parse all the numbers
do
{
ptr = next_number;
long num = strtol(ptr, &next_number, 10);
if (ptr != next_number) // found one
{
numbers[number_count] = (int)num;
printf("Stored %3d into numbers[%d]\n", numbers[number_count], number_count);
number_count += 1;
}
} while(ptr != next_number);
return 0;
}
Outputs:
Stored name [SomeWords]
Stored 19 into numbers[0]
Stored 9 into numbers[1]
Stored 6 into numbers[2]
Stored 2 into numbers[3]
Stored 22 into numbers[4]
Stored 1 into numbers[5]
Stored 0 into numbers[6]
Stored -4 into numbers[7]

Related

printing integer and char using the same argument in c

I have an assignment to implement a board game. I come up with an idea to print integer and char using the same statement for example,
int main() {
char c[2];
c[0]=1;
c[1]='X';
for (int i = 0;i<=1;++i) {
printf("%d", c[i]);
}
return 0;
}
this is not working as I have integer and char in the array. how could i modify this to just use one for loop?
EDIT:
I am trying to implement a noughts and crosses game. So I display my board as
1 2 3
4 5 6
7 8 9
and whenever a player put down a X or O at a position, I want to display my board for example,
1 X 3
4 5 6
7 8 9
You can just print chars. Since your digits are always 1 to 9 you can use chars '1' to '9' (49 to 57) instead.
It's not exactly a code you'd be writing in production, but it's a nice case of a little puzzle and what you can do with C.
int main() {
char c[2];
c[0]='1';
c[1]='X';
for (int i = 0;i<=1;++i) {
printf("%c", c[i]);
}
return 0;
}
I've slightly modified your code to make it clear how that might work.
Your code won't work as intended as you're mixing up two distinct data types. int and char are not the same type of element. They don't even have the same size; the size of char is defined as 1, and the size of int varies by implementation, but is usually 4 or 8. So your array will not even be able to hold ints. When you say:
c[0] = 1;
what is actually happening is that the array stores the char with the ASCII value of 1, which is the "Start of Heading" character.
To do what you want, do not use the int type at all. Use char throughout. That is, write something like this:
c[0] = '1';
Putting the '1' in single quotes makes it a char, not an int. You can use this to fill your 2D array and then make replacements with 'X' and '0' when needed.
You're doing to mistakes here.
You're using c[0]=1; instead of c[0]='1';. You want the character 1 and not the number 1.
You're using printf("%d instead of printf("%c. You want to print a character and not a number.
Here is some example code to achieve what you want:
void print_board(char *board) {
for(int i=0; i<9; i++) {
printf("%c ", board[i]);
if(i % 3 == 2)
printf("\n");
}
printf("\n");
}
void init_board(char *board) {
for(int i=0; i<9; i++)
board[i] = '1' + i;
}
int main(void) {
char board[9];
init_board(board);
print_board(board);
board[2] = 'X';
print_board(board);
board[5] = 'O';
print_board(board);
init_board(board);
print_board(board);
}
The above is not really production code. But it's enough to get you going.
Output:
$ ./a.out
1 2 3
4 5 6
7 8 9
1 2 X
4 5 6
7 8 9
1 2 X
4 5 O
7 8 9
1 2 3
4 5 6
7 8 9

C - Reading Till The EOF, Getting Additional Addresses and Numbers (Array)

So, I have a File full of numbers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
The case is, I don't know the exact number of numbers in this file, so I don't know the exact size of array I will need to write this file info in to this array.
I just gave array much bigger size than I need and I will show you the output, partially it does its job.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#define ARR_SIZE 30
int main(void){
FILE *fp;
int array[ARR_SIZE];
fp = fopen("C:/project/project.txt", "r");
printf("Numbers: ");
for(int i = 0; i < ARR_SIZE; i++){
fscanf(fp, "%d", &array[i]);
}
for(int j = 0; j < ARR_SIZE; j++){
printf("\n%d", array[j]);
}
fclose(fp);
return 0;
}
I am just trying to do standard things, opening file, reading file with for loop, writing all this info to array and outputting array.
Here is the output I get, I understand it is because of the size, but can you tell me how to limit all of these? Easiest way?
Output:
Numbers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
4199136
0
4200896
6422240
6422296
6422476
1998244384
592257989
-2
1998220218
1998220461
4200896
6422368
4200987
4200896
I have array size 30 and numbers in the file 15, first 15 is okay, it is exactly what I need, but I don't need those number after it...
You need a stop-condition for the loop that reads from the file. One option is to stop when you can't scan an item. Use the return value from fscanf to detect that.
When you do the printing only print the number of items actual scan'ed.
Try
for(int i = 0; i < ARR_SIZE; i++){
if (fscanf(fp, "%d", &array[i]) != 1) break; // Stop if the scan fails
}
for(int j = 0; j < i; j++){ // ARR_SIZE replaced by i
printf("\n%d", array[j]);
}
BTW: You should check that fp is valid just after the file open.

Read integers from file in C

1 2 3 4 5
1 2 3 4 5
1 2 3
2 5 7 8 9 8
I'm a beginner of C and I want to write a small program but I have this problem.
The problem is: if there is a file contains integers, the number of integers of each line is different but all within the maximum number of integers.
For example the integers above, the maximum number of integers for each line is 6, each line could have from 1 to 6 integers. The maximum number of integers will also change for each file.
How to store these numbers into a 2D array? Or store the integers into arrays line by line. (Don't worry about the empty values)
I have tried to use fscanf, but I don't know how to define the number of integers of each reading.
================================
Thanks everyone for the generous help, I've figured out using Joachim Pileborg's idea.
#define MAX_SIZE_BUFFER 1000
FILE *file;
int len = MAX_SIZE_BUFFER;
char sLine[MAX_SIZE_BUFFER];
int i, j, maxnumber = 6;
int *numbers, *temp;
char *sTok;
numbers = (int *) malloc(sizeof(int) * maxnumber);
for (i = 0; i < maxnumber; i++) {
numbers[i] = -1;
}
while (fgets(sLine, len, file) != NULL) {
i = 0;
sTok = strtok(sLine, " ");
while (sTok != NULL) {
numbers[i] = atof(sTok);
sTok = strtok(NULL, " ");
i++;
}
/* This temp stores all the numbers of each row */
temp = (int *) malloc(sizeof(int) * i);
for (j = 0; j < i; j++) {
temp[j] = numbers[j];
}
}
The code above is not completed, but it's the idea how I do this.
One way to solve your problem is to start by reading line by line (using e.g. fgets). Then for each line you need to separate the "tokens" (integers) which you can do with e.g. strtok in a loop. Finally, convert each "token" string to an integer using e.g. strtol.
let's try: fscanf(fp, "%d", value)
fp : file pointer.
"%d": format of the value that you want to read (it can be %c, %f, ...).
value: use it to keep the value you just read from the file.
Of course you should put it into the loop if you want to read all content in the file. EOF is the condition to break the loop.

How to scanning lines, each line differently, in c?

Lets say i have this text file for example:
4
1 2 3 4
3 9 8 7
1 1 2 1
8 7 8 6
I want to store the first line ("4") to one variable, and the other lines,
insert them to 2d matrix as the way they showing (dynamic 2d array).
Notice that its just example, i just know that the first line is one char, and i don't know the len of the rest of the lines except that are N*N matrix.
How can i do this in C?
Edited: so the matrix should only have numbers, so sor example this txt file:
4
1 2 3 4
3 9 8 7
1 W 2 1
8 7 8 6 is illegal . how can i handle this?
#include <stdio.h>
#include <stdlib.h>
int main(void){
FILE *fp = fopen("data.txt", "r");
int n;
fscanf(fp, "%d", &n);
int (*mat)[n] = malloc(sizeof(int[n][n]));
int *p = &mat[0][0];
while(p < &mat[n-1][n])
fscanf(fp, "%d", p++);
fclose(fp);
//check
for(int r=0; r < n; ++r){
for(int c=0; c < n; ++c)
printf("%d ", mat[r][c]);
printf("\n");
}
free(mat);
return 0;
}

strange Segmentation fault (core dumped) on matrix

So, I have this part of code:
for (lin = 0; lin < linhas_mat1; lin++)
{
fgets(linha_s, MAX_LINHA, matriz1_file);
buffer = strtok(linha_s, " ");
for (col = 0; col < colunas_mat1; col++)
{
printf ("\nCOLUNA: %d", col);
if (&matriz1[lin][col] == NULL)
printf ("erro");
matriz1[lin][col] = atoi(buffer);
buffer = strtok(NULL, " ");
}
}
It puts a matrix from a file into the memory. The open and the allocation didn't give errors (at least I think). What's strange is that the error seems to occur (discovered by printing the number of the current line) on the last 2 elements (before the last with the code above or the last element if I add some prints, that's even stranger) and only if the matrix has 5 lines or more. The previous lines are added into memory without problem, so I can't see why the last elements give problems. Someone has a clue what's the problem or some tips in how I can find the issue?
The code itself has no problem. The only possible reason I can see is, when the input file has less columns than you specified, it will cause a segmentatioin fault.
Here is full version of your code, I only added some initializations
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int lin, col, linhas_mat1, colunas_mat1;
char* buffer;
char linha_s[1023];
int matriz1[8][5];
linhas_mat1 = 8; colunas_mat1 = 5;
const int MAX_LINHA = 20;
FILE *matriz1_file = fopen("aa.txt", "r");
for (lin = 0; lin < linhas_mat1; lin++)
{
fgets(linha_s, MAX_LINHA, matriz1_file);
buffer = strtok(linha_s, " ");
for (col = 0; col < colunas_mat1; col++)
{
//printf ("\nCOLUNA: %d", col);
if (&matriz1[lin][col] == NULL)
printf ("erro");
matriz1[lin][col] = atoi(buffer);
printf("%d ", matriz1[lin][col]);
buffer = strtok(NULL, " ");
}
printf("\n");
}
}
If you give following file as input, the matrix will get all the values without any problem, unless you remove some column from it.
1 2 9 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

Resources