This question already has answers here:
fscanf into a 2d array in C
(2 answers)
Closed 4 years ago.
So i have a 20 x 20 array, and its all filled with -1.
I also have an input.txt which contains some numbers, for example :
2,3
5,6
How can i fill my array so that array[0][0] will be 2,
array[0][1] will be 3, array[1][0] will be 5, array[1][1] will be 6, and every other element will be -1.
I've tried with a for loop thats using fscanf until there is a new line, but that won't work.
I've tried with a for loop thats using fscanf until there is a new line, but that won't work.
Variations on fscanf(in, "%d,%d\n", &x, &y), as in OP's prior question, fail to detect end-of-line. The '\n' in the format will match any white-space on input including '\n', ' ', '\t',etc.
Simplistic usage of fscanf(..., "%d",...) can readily fail as "%d" will consume all leading white-space with no discrimination between '\n' and other white-spaces.
How can i fill my array ...
Although possible to use fscanf() to solve this task, consider fgets(), strtol().
The best approach is to use fgets() to reach a line: all characters up to and including the one final '\n'. Then use strtol(), strtoll(), etc. to read the integers.
long integers and spacing each needs reasonable less than 21 characters. To accommodate extra leading zeros spacing, etc, let use 2x the anticipated size needs.
#define CHAR_PER_NUMBER 21
#define NUM_PER_LINE 20
#define LINE_NUM 20
#define LINE_SIZE (NUM_PER_LINE * CHAR_PER_NUMBER * 2)
long array[LINE_NUM][NUM_PER_LINE];
// read data
for (int i = 0; i < LINE_NUM; i++) {
char buf[LINE_SIZE + 1]; // +1: room for the appended the null character
if (fgets(buf, sizeof buf, in) == NULL) {
buf[0] = '\0';
}
// Now parse the line
char *p = buf;
for (int j = 0; j < NUM_PER_LINE; j++) {
char *endptr;
array[i][j] = strtol(p, &endptr, 10);
if (p == endptr) {
array[i][j] = -1; // no conversion
}
p = endptr; // advance to the next number
}
}
Additional concerns including handling pathological long lines, values outside the long range, I/O error handling and efficiency details.
Should input consists of text representing floating-point, a more generous max size per value is warranted.
Try using "end of file"(eof), where m and n are the rows and columns
for (i = 0; i < m && !feof(input); i++)
for (j = 0; j < n && !feof(input); j++)
fscanf(input, "%f", &a[i][j]);
If the size of the array (m and n) is also given in the file write an if condition before
if (!feof(input))
fscanf(input, "%d %d", &m, &n);
for (i = 0; i < m && !feof(input); i++)
for (j = 0; j < n && !feof(input); j++)
fscanf(input, "%f", &a[i][j]);
Related
int main() {
#define MEMSIZE 100
int memory[MEMSIZE] = {0};
int i = 0;
char *temp = malloc(sizeof(100));
fgets(temp, MEMSIZE, stdin);
for (i = 0; i < (sizeof(memory)/sizeof(int)); i++) {
memory[i] = temp[i];
}
for (n = 0; n < 10; n++) { // Print contents
printf("%d - %d\n", n, memory[n]);
}
}
So today I have what seems to be a very simple question. I am taking a file from stdin, using:
./a.out < filename
My main goal is to take in the numbers provided in the file, and store them into a 1 dimensional array. My current use of fgets() works correctly, reading in line one and copying those elements into my 1D array (their ASCII values converted to int). Now, to read in my next lines, if I call fgets() again, the next line is read but it is then stored in the same place as the first values, thus overwriting them in my array in position 0-3. These values need to be stored successively in my array until EOF.
The file is in the format:
1234
5678
...
#include <stdio.h>
#define MEMSIZE 100
int main() {
int memory[MEMSIZE] = {0};
int i,n;
for (i = 0; i <MEMSIZE; i++){
if(fscanf(stdin,"%d", (memory+i))==EOF){
break;
}
}
//i is the number of ints you got
for (n = 0; n < i; n++) { // Print contents
printf("%d - %d\n", n, memory[n]);
}
return 0;
}
I dont see a reason to use dynamic allocation over here as a temp variable.
If the file is list of numbers, just read as a number, no need for fgets over here, if you still want to read it as a string, have a look at atoi func
sizeof(memory)/sizeof(int)= (sizeof(int)*MEMSIZE)/sizeof(int)= MEMSIZE
You shouldn't just loop MEMSIZE times, you need to know when it EOF
I dont know why you assumed in the printing loop that 10 is enough, i changed it to i which is number of elements
You didnt define n
I hope that i helped.
I am writing a program that will ask the user for a 'n' value, they will then enter 'n' values that will be stored into an array and sorted. I have this part done easy enough.
I will compare this array with input from a number read from a text file. If the number is bigger than any of the current array values it will replace them and slide the rest down. This creates an array of the largest 'n' values
Example: n = 4 n values are : 999 972 954 462 937
a[4] = {999, 972, 954, 462, 937};
Sorted :
a[4] = {999, 972, 954, 937, 462};
if the file input is say 968 the result is.
Resorted :
a[4] = {999, 972, 968, 937, 937};
This is my current code.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
if (argc<3) //error checking
return -1;
int size = atoi(argv[2]);
int a[size];
int i, j, temp=0;
printf("Enter %d numbers\n", size); //user array input for size and n values
for(i = 0; i < size; i++)
scanf("%d", &a[i]);
for(i=0; i < size; i++){ //sorting array
for(j = i+1; j <size; j++){
if( a[i] < a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
FILE *input;
input = fopen(argv[1], "r");
if(input ==NULL) //error checking
return -1;
if(fscanf(input, "%d", &temp) != 1)
return -1;
while(fscanf(input, "%d", &temp) ==1){ //loop while there is file input
for(i =1 < size; i++){ //check if temp is larger than array values
if(temp > a[i] && temp < a[i-1]){
for(j = size-1; j >= i; j--) //slide down the rest of the array
a[j] = a[j-1];
a[i] = temp;
}
}
}
for(i=0; i <size; i++){ //print out array
printf("%d ", a[i]);
}
return (0);
}
I have tried this on a smaller simpler skill were I have already created the array and the values instead of using user input. I also just passed the array check sequence through a loop that increases a number value instead of reading from a file. This seemed to work fine with something like
a[5] = {10, 8, 6, 4, 2};
number = 5; // number++ number = 6 number = 7... until 10
result: a[5] = {10, 9, 8, 7, 6};
I am sad to say that even if the program was not printing the right array at the beginning I could see there were numbers from the file. The loop is still going trough the file, but at one point the output just started being the sorted user array. I can't seem to get the array values right. Any ideas?
Continuing from my comments yesterday, I apologize if the errors were due to the retyping of your code, but that is the whole reason you want to try to cut and paste as Jonathan indicated -- eliminate human error in the transcription process.
I think I understand what your primary problem is. If your goal is to read some number of user input values from stdin, sort them in descending order, and then open a file and read a single additional value into the array in sort-order, then you must provide space for the final value in your array at the time it is declared (if using VLA's). Otherwise, you either need to create a second VLA large enough to store the values from the use and the file, and copy the user provided values to the new array or dynamically allocate the array originally (with malloc or calloc) and then realloc as needed to add space for additional values as required.
In this case, it's not that difficult since you know you are reading one value from the file. Just read the size from the command line argument and then create your array as int a[size + 1];
The rest of your task can be handled in a couple of ways. After you read (and validate) the user input, you can sort your values in descending order, read the value from the file, and create an insert & shuffle routine to insert the value in the correct order and move the remaining array elements down, or (probably a less error prone method) is simply to add the element from the file to the end of the array, and call your sort routine again.
(note: you should get used to using qsort rather than attempting to reinvent the bubble-sort, etc.. It is orders of magnitudes more efficient and much less error prone)
You need limit (or eliminate) your use of atoi as it provides zero error checking. A better approach is to use strtol and then check errno and check the end-pointer against the original to determine if there were any digits read. Below a simple helper function incorporates error-checking for strtol to insure you have an actual value for size.
Further, be careful. While you may expect the user will enter size integer values, there is no guarantee they will. It is better to track the number of values actually entered and use that value in subsequent iterations over the array rather than blindly iterating for (i = 0; i < size; i++) throughout the remainder of your code.
Whether you attempt an insert-in-place of the value read from the file, or just add it to the end of the array and call your sort routine again is up to you. I would encourage you to move your sort code into a function to provide that flexibility without having to duplicate the code in main. Look the following over and let me know if you have any questions. Since I presume this was a homework assignment, the insert-in-place case is shown below (but the simple add the file value to the end and call sort again code is included commented out)
#include <stdio.h>
#include <stdlib.h> /* for strtol */
#include <limits.h> /* for LONG_MAX/MIN */
#include <errno.h> /* for ERANGE,errno */
void sort_int_array_dec (int *a, size_t size);
long xstrtol (char *p, char **ep, int base);
int main (int argc, char **argv) {
/* read size as first argument, or 5 if none given */
int size = argc > 2 ? (int)xstrtol (argv[2], NULL, 10) : 5,
a[size + 1], /* variable length array for user + file values */
n = 0, /* number of values from user */
fval, /* value read from file */
temp, /* temporary value for array */
i = 0;
FILE *fp = NULL;
if (size < 1) return 1;
printf ("enter %d integers\n", size);
while (n < size) { /* read up to size values */
int result, c;
printf (" integer[%2d] : ", n + 1);
/* validate read of each value using scanf return */
if ((result = scanf ("%d", &temp)) != 1) {
if (result == EOF) { /* always check for EOF */
fprintf (stderr, "user canceled input.\n");
break;
}
fprintf (stderr, "error: invalid conversion.\n");
/* empty input buffer of invalid entry */
while ((c = getchar()) != '\n' && c != EOF) {}
}
else /* good value read, save, increment n */
a[n++] = temp;
}
sort_int_array_dec (a, n); /* sort a */
printf ("\nsorted array before inserting value from file:\n\n");
for (int i = 0; i < n; i++)
printf ("a[%2d]: %d\n", i, a[i]);
if (!(fp = fopen (argv[1], "r"))) {
fprintf (stderr, "error: file open failed '%s'\n", argv[1]);
return 1;
}
if (fscanf (fp, "%d", &fval) != 1) { /* read value from file */
fprintf (stderr, "error: read of file value failed.\n");
return 1;
}
printf ("\n value from file: %d\n\n", fval);
/* add fval into array in descending sort order
* (you can add it anywhere and simply call sort again, e.g.)
*/
// a[n] = fval; /* add it to the end of the array */
// sort_int_array_dec (a, n + 1); /* sort a again */
for (i = 1; i < n + 1; i++) {
if (fval > a[i-1]) {
temp = a[i-1];
a[i-1] = fval;
break; /* temp now holds value to insert at i */
}
}
if (i == n + 1) /* if already at last element just set it */
a[n] = fval;
else /* otherwise, insert and shuffle remaining elements down */
for (int j = i; j < n + 1; j++) {
int mov = a[j];
a[j] = temp;
temp = mov;
}
printf ("sorted array after inserting value from file:\n\n");
for (int i = 0; i < n + 1; i++)
printf (" a[%2d]: %d\n", i, a[i]);
return 0;
}
/** sort integer array descending (your code) */
void sort_int_array_dec (int *a, size_t size)
{
size_t i, j;
int temp;
if (size < 2) return; /* nothing to sort */
for (i = 0; i < size; i++) {
for (j = i + 1; j < size; j++) {
if (a[i] < a[j]) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
/** a simple strtol implementation with error checking.
* any failed conversion will cause program exit. Adjust
* response to failed conversion as required.
*/
long xstrtol (char *p, char **ep, int base)
{
errno = 0;
char *endpt = ep ? *ep : NULL;
long tmp = strtol (p, &endpt, base);
/* Check for various possible errors */
if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
(errno != 0 && tmp == 0)) {
perror ("strtol");
exit (EXIT_FAILURE);
}
if (endpt == p) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}
if (ep) *ep = endpt;
return tmp;
}
Example Use/Output
$ cat dat/file.txt
523
$ ./bin/addintoarray dat/file.txt 4
enter 4 integers
integer[ 1] : 400
integer[ 2] : 500
integer[ 3] : 600
integer[ 4] : 700
sorted array before inserting value from file:
a[ 0]: 700
a[ 1]: 600
a[ 2]: 500
a[ 3]: 400
value from file: 523
sorted array after inserting value from file:
a[ 0]: 700
a[ 1]: 600
a[ 2]: 523
a[ 3]: 500
a[ 4]: 400
/*I'm a beginner C programmer so I don't know much of the syntax.
But I think I can help you with that problem.
I created a simple code and I hope I can really help
the integers from the file must be already sorted.
So the only integer that we will sort is the recent integer that the user inputed.
*/
/*So here's my code of sorting array of integers coming from file.
Please give it a try.
It's not the same syntax as your code but I know you can see my point*/
#include <stdio.h>
#include <stdlib.h>
//my style here is I'm declaring the max Num that I want to put in array.
//But you can do this with different style.
#define MAX_ARRAY 10
//I created separate functions
void readFile(int num_arr[]);
void sortArray(int num_arr[]);
void writeFile(int num_arr[]);
int main()
{
int num_arr[MAX_ARRAY + 1]; // take note that I added 1 (one). And you will see later why I did that
readFile(num_arr);
sortArray(num_arr);
writeFile(num_arr);
//Now we can sort them. Use a temp_num holder.
return 0;
}
void readFile(int num_arr[])
{
int x = 0;
int y = 0;
int temp_num;
FILE *sample_file_pointer = fopen("sample_file.txt", "r");
//first I read the integers from the file and put them in int array.
while(fscanf(sample_file_pointer, " %d\n", &num_arr[x]) == 1)
{
x++;
}//after reading the integers, the last element of the array we declared is still unused.. Now we will use it.
fclose(sample_file_pointer);
//now we will use the unused element by entering the 'n'. Then we will sort the array later.
printf("Enter value of n: ");
scanf(" %d", &num_arr[MAX_ARRAY]);//We put the n value in the last element of the array
}
void sortArray(int num_arr[])
{
int x = MAX_ARRAY;//We will use this to point the last element of the array.
int temp_num;
/*because the array from
the file is already
sorted, (I know you can
do the sorting of that.
That's why I didn't include
it here to make this short)
we can just test the most recent
integer that is added by the user*/
//We do that with this loop
for(int i = MAX_ARRAY; i > 0; i--)
{
if(num_arr[x] >= num_arr[i - 1])
{
temp_num = num_arr[x];
num_arr[x] = num_arr[i - 1];
num_arr[i - 1] = temp_num;
//now set the x to the swapped element to follow the recent number all through. Till the element test becomes 1.
x = i - 1;
}
}
//now we're ready to write this sorted array to a file again
}
void writeFile(int num_arr[])
{
FILE *sample_file_pointer = fopen("sample_file.txt", "w");
for(int i = 0; i < MAX_ARRAY; i++)
{
fprintf(sample_file_pointer, "%d\n", num_arr[i]);
}
//We can ignore the last element of the array. She's out of the group now. It's her fault for being the lowest.. LOL..
fclose(sample_file_pointer);
}
I am using C as my programming language (not C++) and I am required to encrypt whatever the user types in using a 2-rail fence cipher method of coding in C, AND then pad whatever empty space there is left in the encrypted name with an 'x'. Because it's 2-rail fence the empty space happens if the output string has ODD number of characters!
Here is an example.
Let's say someone write this name: andredimera (all lowercase, no space). The name is 11 characters long. If padding with the x is done correctly, the encrypted name should give me this output WITH the padding -->
adeiea
nrdmrx
adeieanrdmrx
But I keep getting this output without the padding-->
adeiea
nrdmr
adeieanrdmr
This is FRUSTRATING! This has been a class quiz for almost a week now, I have not done well, and nobody has been able to help me out no thanks to my short-term memory. I would really appreciate this if someone can help me solve this, with an explanation on how you came up with the solution, so I can get it right in future endeavors. I don't want just the hint or explanation for me to go fish it out myself. I've had my share of it already this week. Thank you. I appreciate your help. :)
Oh, and here is my code:
UPDATED: Code was reposted because I was stupidly compiling it in a completely different solution. That code should work now.
Which now brings me to my latest question based on my updated code: how can I make my char pad = 'x' be added into my char str if the user input has odd number of characters?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
char row, col;
char str[100][100];
char pad = 'x';
printf("****Welcome to The Caesar's Palace for Encrypted Names****");
printf("\n Please enter your name: ");
scanf("%s", str);
printf("You entered: %s\n", str);
printf("2-RAIL CIPHER ENCRYPTION:\n");
for (row = 0; row < 1; ++row)
{
for (col = 0; col < 12; col += 2)
{
printf("%c", str[row][col]);
}
printf("\n");
for (col = 0; col < 12; col += 2)
{
printf("%c", str[row][col + 1]);
}
}
printf("%c", pad);
printf("\n");
for (row = 0; row < 1; ++row)
{
for (col = 0; col < 12; col += 2)
{
printf("%c", str[row][col]);
}
for (col = 0; col < 12; col += 2)
{
printf("%c", str[row][col + 1]);
}
}
printf("\n");
printf("\n");
return 0;
}
There are a number of fundamental issues that are giving you problems. The biggest being the understanding of what a character, character array and string is in C, and how to declare/initialize each. Your pad is a single char, there are no additional dimensions required during the declaration and initialization. It is simply:
char pad = 'x';
A character array is just that multiple characters. In C, if the contents of a character array is nul-terminated, then it can be used as a string. Without the nul-termination it is simply an array of characters.
In your case, you are attempting a 2-Rail cipher with a key (number of rows of text) of 2. Meaning you will simply stagger the characters from the name read from the user between the top-rail and bottom-rail across two lines. e.g.
word: ALLIGATOR
len : 12 characters max (11 char + nul-terminator)
key : 2 (number of lines of text)
0 1 2 3 4 5 6 7 8 9 10
------------------------- rail 1
A x L x G x T x R x x
x L x I x A x O x x x
------------------------- rail 2
The string you take as input need only be a single-dimension array of characters (nul-terminated). As such, your declaration of str, with the number of columns (NCOL = 12), need only be:
char str[NCOL] = ""; /* a 12 character array initialized to 0 (empty string) */
Since your row and col variables are used as array indexes, they should properly be type int instead of type char. (that is another compiler warning)
The remainder of your code, isn't far off. There is no need for the outer row loop in your 2-Rail cipher code, iterating from 0 < 1 with only execute once.
Your padding issue is simply due to the way the rail-cipher works. For each line in key you add, you need to add that number of padding characters. (e.g after the original line, for the 1st line, you add one x before the text, 2 before the second, etc..) In your case, you are simply missing one x before the line following the original. You can correct the issue here with a simple:
printf ("\nx");
between the column loops.
Putting those pieces of the puzzle together with a few more corrections (such as preventing overrun of str by a field-width limitation in scanf, etc.), you could do something like:
#include <stdio.h>
enum { KEY = 2, NCOL = 12 }; /* simple decalration of 2 constants */
int main (void) {
char str[NCOL] = "";
char pad = 'x';
int row, col;
printf ("\n****Welcome to The Caesar's Palace for Encrypted Names****\n");
printf ("\n Please enter your name: ");
scanf ("%11[^\n]%*c", str);
printf (" You entered: %s\n\n", str);
printf ("2-RAIL CIPHER ENCRYPTION:\n\n");
for (col = 0; col < NCOL; col += KEY) {
printf ("%c%c", str[col], pad);
}
printf ("\nx");
for (col = 0; col < NCOL; col += KEY) {
printf ("%c%c", str[col + 1], pad);
}
printf ("\n\n Your new name is now \n\n");
for (col = 0; col < NCOL; col += KEY) {
printf ("%c%c", str[col], pad);
}
for (col = 0; col < NCOL; col += KEY) {
printf ("%c%c", str[col + 1], pad);
}
printf ("\n\nCAESAR CIPHER ENCRYPTION:\n\n");
printf (" Your new name is now\n\n");
for (row = 0; row < NCOL; ++row) {
char c = str[row];
c = (char) (c + KEY + 1);
printf ("%c%c", c, pad);
}
printf ("\n");
printf ("\n");
printf ("The End\n");
return 0;
}
Example Use/Output
$ ./bin/railcipher
****Welcome to The Caesar's Palace for Encrypted Names****
Please enter your name: ALLIGATOR
You entered: ALLIGATOR
2-RAIL CIPHER ENCRYPTION:
AxLxGxTxRxx
xLxIxAxOxxx
Your new name is now
AxLxGxTxRxxLxIxAxOxxx
CAESAR CIPHER ENCRYPTION:
Your new name is now
DxOxOxLxJxDxWxRxUxxxx
The End
note: I make no representations about the correctness of your CAESAR cipher and I'm no expert on rail-ciphers, but the syntax and code corrections must be dealt with before you tweak the ciphers. Look over the changes and let me know if you have any questions.
Here are what you need to do to fix your codes:
Step 1 Add a define hashtag and the include string library to the top of your code...
#include <string.h>
#define BUFFER_SIZE 100
Step 2 Replace these following members that you have...
char row, col;
char str[100][100];
char pad = 'x';
...to these ones
int col, size;
char str[BUFFER_SIZE];
Step 3: Right below your scanf, define your size with a strlen. Strlen calculates and returns to you the length of a string. Any string that you input. This is my strlen for your problem. Use it. ;)
size = strlen(str);
Step 4:
From 2-Rail cipher encryption till the last printf function, replace your code to the ones below.
for (col = 0; col < size; col += 2)
{
printf("%c", user[col]);
}
printf("\n");
for (col = 0; col < size; col += 2)
{
//printf("%c", user[col + 1]);
if (col + 1 != size)
printf("%c", user[col + 1]);
else
printf("x");
}
printf("\n");
for (col = 0; col < size; col += 2)
{
printf("%c", user[col]);
}
for (col = 0; col < size; col += 2)
{
if (col + 1 != size)
printf("%c", user[col + 1]);
else
printf("x");
}
In case you need explanation, your issue was simple, you had an extra row in your C-string that the program was not using. Additionally, you needed the strlen and an if function that basically says "if you've reached the end of the character string in an array of more than 100 characters, then print an x. If you did not have that code in the program would either print nothing (as stated in your issue) or print a zero.
But, keep in mind that if you type in a super long C-string name that is more than 100+ characters and you have the x padding at the end, it will cause some memory issue. Just food for thoughts.
But from now, do these steps and your codes should work with the output you wanted. (hopefully it should). This was my ouput.
adeiea
nrdmrx
adeieanrdmrx
Write a declaration for a two dimensional array A that has 5 rows and 10 columns and in which each element is a character string of length 20. What is the sizeof A?
Part II: Write statements to set each element in the array to a string of blanks.
This is first year programming so everything is very basic. This is in C.
Thanks for any help.
Here's my attempt for part I
char c[5][10][20];
Here's my attempt for part II
int x,y;
for (x=0;x<5;x++) {
for (y=0;y<10;y++) {
c[x][y]=" "; }}
I don't know if I'm misreading your question or whether it really is as straight forward as finding the size of your 5 * 10 * 20 character array? The sizeof type char is 1-byte per-char. Thus 5 * 10 * 20 = 1000 (as compared to say a type int which would normally be 4-bytes per-int).
To determine the size within the scope where the array is statically declared you can use the sizeof operator, for example:
#include <stdio.h>
int main (void) {
char c[5][10][20];
printf ("\n sizeof c : %lu\n\n", sizeof c);
return 0;
}
Use/Output
$ ./bin/sizeof_3d
sizeof c : 1000
To set each element in the array to ' ' (space), you have a couple of options (1) a loop over each element in the array; or (2) using memset. To use a loop:
size_t i, j, k;
...
for (i = 0; i < 5; i++)
for (j = 0; j < 10; j++)
for (k = 0; k < 20; k++)
c[i][j][k] = ' ';
If you need a literal string of blanks you will need to add a nul-terminating character as the final character in each string. When using the loop above, that can be accomplished by replacing c[i][j][k] = ' '; with the following that uses a ternary operator to write a nul-character (zero) as the final character in each string:
c[i][j][k] = k + 1 == 20 ? 0 : ' ';
To use memset (don't forget to #include <string.h>):
memset (c, ' ', sizeof c);
To null terminate following the use of memset, an abbreviated loop can be used:
size_t i, j, k;
...
memset (c, ' ', sizeof c);
for (i = 0; i < 5; i++)
for (j = 0; j < 10; j++)
c[i][j][19] = 0;
Let me know if you have further questions.
First declare a type for your 20 character strings.
typedef struct mystring {
char str[20];
} mystring;
Then you can declare your variable A LIKE THIS:
mystring A[5][10];
So, A is a variable of type 5 string which has 5 rows and 10 columns. Each element in the array is of type mystring which as a string that can hold 20 characters. The maximum length of a string that a mystring can hold is of course 19 characters since you need to reserve one character for the null terminator.
An array A that has 5 rows and 10 columns and in which each element is a character string of length 20.
What is the sizeof A?
The size of array A we get by multiplying its columns by its rows and the result of it multiplying by the size of the elements of the array. In this case they are strings of 20 characters length. Assuming your machine's char implementation is 1 byte, then array A occupies total size of:
5 x 10 x 20 = 1000 bytes or 1MB.
To define such an array in C++, you write within your main, avoiding magic numbers:
size_t rows_number = 5;
size_t columns_number = 10;
size_t element_size = 20;
char c[rows_number][columns_number][element_size];
To initialize its elements to particular value, you could use for loops for each index of the array:
char initial_value = ' ';
for (i = 0; i < row_number; i++) {
for (j = 0; j < column_number; j++) {
for (k = 0; k < element_size; k++) {
c[i][j][k] = initial_value;
}
}
}
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.