i have a file with several rows of 10 integers.
i want to copy those integers into several arrays, named line1, line2, line3 etc with numbers from each row in a corresponding array.
i am currently using
fscanf(items, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d", &line1[0], &line1[1], &line1[2], &line1[3], &line1[4], &line1[5], &line1[6], &line1[7], &line1[8], &line1[9]);
to assign the first 10 ints to an array named line1.
this is a really sloppy way to do it, and it doesn't tackle the other issue of assigning the rest of the values to other arrays.
any suggestions on how to assign 10 values to an array more neatly, and how to assign each row to a different array would be greatly appreciated!
thanks
Use a multidimensional array and nested loops:
#DEFINE COLS 10
#DEFINE ROWS 10
int i, j;
int line[ROWS][COLS];
for (i = 0; i < ROWS; ++i) {
for (j = 0; i < COLS - 1; ++j) {
fscanf(items, "%d, ", &line[i][j]);
}
fscanf(items, "%d", &line[i][COLS - 1]);
}
Edit:
The code above uses the same format string as the question (comma-separated values).
If space-separated values are ok, you can use a straight loop without the separate fscanf for the last item on each row:
#DEFINE COLS 10
#DEFINE ROWS 10
int i, j;
int line[ROWS][COLS];
for (i = 0; i < ROWS; ++i) {
for (j = 0; i < COLS; ++j) {
fscanf(items, "%d", &line[i][j]);
}
}
Side note:
If you want to write code that detects errors in the input file you need to check the return value from fscanf. Probably not required in a school project, but required in industrial-strength code.
If you know how many lines you have, say 100, you could just:
int arr[r][c];
for (i=0; i<r; i++) {
for (j=0; j<c-1; j++) {
fscanf(file, "%d, ", &arr[i][j]);
}
fscanf(file, "%d\n", &arr[i][j]);
}
You need to use loops.
#include <stdio.h>
for (size_t i = 0; i < 9; ++i)
fscanf("%d, ", &line1[i]);
fscanf("%d", &line[9]);
It would be even better to have a bidimensionnal array.
int a[NLINES][NCOLUMNS];
for (size_t i = 0; i < NLINES; ++i) {
for (size_t j = 0; j < NCOLUMNS - 1; ++j)
fscanf(fp, "%d, ", &a[i][j]);
fscanf(fp, "%d\n", &a[i][NCOLUMNS - 1]);
}
Related
I am trying to copy a 1D array of Strings into a 2D array of strings in C.
I was able to achieve this with integer
enter image description here
//Here is what I tried for integers.
int main()
{
int arr[3][3];
int arr2[9]={1,2,3,4,5,6,7,8,9};
int i,j,k=0;
for(i=0; i<3;i++){
for(j=0; j<3;i++){
arr[j][i] = arr2[i];
//rintf("%d\n",arr2[i]);
}
}
for(i=0; i<3; i++) {
for(j=0; j<3; j++)
printf("%2d ", arr[j][i]);
printf("\n");
}
return 0;
}
I changed my data to char and I tried to run the same code I got a segmentation error.
Here is what I have tried so far and it didnt work. error :Segmentation fault (core dumped)
#include<stdio.h>
#include<string.h>
int main()
{
char *d[3][3]; // Destination array
char *s[9]={"orange","apple","table","chair","cable","TV", "124","HI"}; // Source 1 Day array
int i,j,k=0;
for(i=0; i<3;i++){
for(j=0; j<3;i++){
strcpy(d[j][i], s[i]);
}
}
for(i=0; i<3; i++) {
for(j=0; j<3; j++)
printf("%s ", d[j][i]);
printf("\n");
}
return 0;
}
I have made some adjustment and now it print some weird strings
#include<stdio.h>
#include<string.h>
int main() {
char d[3][3] ={0}; // Destination array
char s[9][8]={"orange","apple","table","chair","cable","TV", "124","HI"}; // Source 1 Day array
int i,j,k=0;
for(i=0; i<3;i++){
for(j=0; j<3;j++){
d[j][i] = *s[i];
}
}
for(i=0; i<3; i++) {
for(j=0; j<3; j++)
printf("%s ", &d[j][i]);
printf("\n");
}
return 0;
}
enter image description here
This for loop
for(i=0; i<3;i++){
for(j=0; j<3;i++){
arr[j][i] = arr2[i];
//rintf("%d\n",arr2[i]);
}
}
is incorrect. In the inner loop there are used the same elements arr2[i] where i is changed from 0 to 2 inclusively.
You need to write
for(i=0; i<3;i++){
for(j=0; j<3;i++){
arr[j][i] = arr2[ 3 * i + j];
}
}
Another way to write loops is the following
for ( i = 0; i < 9; i++ )
{
arr[i / 3][i % 3] = arr2[i];
}
As for arrays of pointers of the type char * then the nested loops will look similarly
for(i=0; i<3;i++){
for(j=0; j<3;i++){
d[i][j] = s[ 3 * i + j];
}
}
provided that the array s is declared like
char * s[9]={"orange","apple","table","chair","cable","TV", "124","HI"};
And to output the result array you need to write
for(i=0; i<3; i++) {
for(j=0; j<3; j++)
printf("%s ", d[i][i]);
^^^^^^^
printf("\n");
}
As for your last program then it can look like
#include<stdio.h>
#include<string.h>
int main( void )
{
char d[3][3][8] ={0}; // Destination array
char s[9][8]={"orange","apple","table","chair","cable","TV", "124","HI"}; // Source 1 Day array
for( size_t i = 0; i < 3; i++ )
{
for ( size_t j = 0; j < 3;j++ )
{
strcpy( d[j][i], s[3 * i + j] );
}
}
for ( size_t i = 0; i < 3; i++ )
{
for ( size_t j = 0; j < 3; j++ )
{
printf( "%s ", d[i][j] );
}
putchar( '\n' );
}
return 0;
}
Some issues ...
d is unitialized so the pointers within point to random locations.
To fix, we need to use malloc to get space and then do strcpy. An easier way is to just use strdup. Or, just assign the s value directly.
Your j loop should increment j and not i.
Using s[i] will repeat after three elements. To fix, we can do: s[k++]
You are short one initializer for s (i.e. it is length 9 but you have only 8 strings).
Here is the refactored code:
#include <stdio.h>
#include <string.h>
int
main(void)
{
char *d[3][3]; // Destination array
char *s[9] = {
"orange", "apple", "table", "chair", "cable", "TV", "124", "HI",
#if 1
"raindrops"
#endif
}; // Source 1 Day array
int i, j, k = 0;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
// NOTE/BUG: we must allocate space for d[j][i]
#if 0
strcpy(d[j][i], s[i]);
#else
d[j][i] = strdup(s[k++]);
#endif
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
printf("%s ", d[j][i]);
printf("\n");
}
return 0;
}
Here is the output:
orange apple table
chair cable TV
124 HI raindrops
There's numerous big problems here.
You could have simply solved this with memcpy(arr, arr2, sizeof *arr2);
(Probably the least of your problems, but...) This is badly written performance-wise: for(j=0; j<3;i++){ arr[j][i] = arr2[i]; Multiple loops should always have the inner-most loop work with the inner-most array item, in this case it should have been arr[i][j], or you get needlessly bad data cache performance.
for(j=0; j<3;i++) How about j++.
char *d[3][3]; is an uninitialized 2D array of pointers, each pointing at la-la-land. So you can't copy jack into those addresses - pointers need to point at valid, allocated memory.
char d[3][3] is a 2D array of 3x3 characters, so it can't contain the data you wish to store there, let alone the mandatory null terminators required for strings to work.
char *s[9] = ... In case you meant the 9th item to be NULL, a so-called sentinel value, you should type out NULL explicitly or otherwise the reader can't tell if a NULL sentinel is intended or if you just sloppily added one by accident.
As you can tell from previous comments, the overall slopiness is a recurring major problem here. Take for example:
for(j=0; j<3; j++)
printf("%s ", &d[j][i]);
printf("\n");
Because of sloppy indention, we can't tell if the printf("\n"); was intended to sit inside the inner loop or not (it is not, despite the indention). You can't just type some almost correct stuff down in a hurry. You have to carefully type down actually correct code. There's various myths that great programmers are smart, great at math or abstract thinking etc - in reality, great programmers are careful and disciplined, taking some pride in their own craft.
The quick & dirty fix is to use the second example char* d[3][3] and then instead of strcpy use strdup (currently non-standard, soon to become standard):
for(size_t i=0; i<3; i++){
for(size_t j=0; j<3; j++){
d[i][j] = strdup(s[i]);
}
}
(And ideally also call free() for each item in d at the end.)
But the root problem here is that you need to go back and carefully study arrays, pointers and strings, in that order, before using them.
I would need some help after googling like 2 hours with no luck. (Maybe i'm just formulating my question incorrectly?)
I need to read 10 words from keyboard, and show a warning if any of the last 9 words are bigger than the first word.
I know how to use strlen to determine the last part of the request, but I have no idea how to do the first one.
My code looks like this:
const int ARRAY_SIZE = 10;
const int MAX_WORD_SIZE = 101;
int main() {
char arr[ARRAY_SIZE][MAX_WORD_SIZE];
for (int i = 0; i < ARRAY_SIZE; ++i) {
for (int j = 0; j < MAX_WORD_SIZE; ++j) {
printf("Add word %d:\n", i+1);
scanf("%s", arr[i][j]);
}
}
return 0;
}
But it does not work. cLion tell me "Format specifies type 'char *' but the argument has type 'int'".
I really don't understand why this doesn't work.
"%s" expects a memory address to where it is supposed to start saving the string.
You have a two dimensional array arr[ARRAY_SIZE][MAX_WORD_SIZE];. When you use [] once you get a 1-dimension array, which is what %s expects.
But since you are using [] twice, you are getting a single element of that array type, which is char.
change your scanf to: scanf("%s", arr[i]); to fix that.
Having noticed that, you can get rid of the inner for loop and variable j.
for (int i = 0; i < ARRAY_SIZE; ++i) {
printf("Add word %d:\n", i+1);
scanf("%s", arr[i]);
}
The solution to your problem would be:
const int ARRAY_SIZE = 10;
const int MAX_WORD_SIZE = 101;
int main() {
char arr[ARRAY_SIZE][MAX_WORD_SIZE];
for (int i = 0; i < ARRAY_SIZE; ++i) {
printf("Add word %d:\n", i+1);
scanf(" %s", arr[i]);
}
return 0;
}
It is a good practice to put a blank space in " %s". This way, chars such us \n are ommited, and many problems which stem from here are avoided.
If you wanted to do
for (int i = 0; i < ARRAY_SIZE; ++i) {
for (int j = 0; j < MAX_WORD_SIZE; ++j) {
printf("Add word %d:\n", i+1);
scanf("%s", arr[i][j]);
}
}
you would be reading character by character, so you would have to do instead:
for (int i = 0; i < ARRAY_SIZE; ++i) {
for (int j = 0; j < MAX_WORD_SIZE; ++j) {
printf("Add word %d:\n", i+1);
scanf("%c", arr[i][j]);
}
}
This way of solving the problem may give rise to another problem: not all words have the maximum size so this would be fixed by:
for (int i = 0; i < ARRAY_SIZE; ++i) {
for (int j = 0; j < MAX_WORD_SIZE; ++j) {
printf("Add word %d:\n", i+1);
scanf("%c", arr[i][j]);
if(arr[i][j]=='\n'){
break;
}
}
}
Anyway, the first one is the best solution.
I have to read the number of rows and columns of a matrix from a txt file also its elements. the first row is the number of rows and columns followed by its numbers. For example this is a matrix with 2 rows and 3 columns containing 123 456 and a matrix with 3 rows and 2 columns.
2 3
1 2 3
4 5 6.
3 2
1 2
3 4
5 6
What I have to do is to read two matrix from the same text file and multiply them. I'm encountering some unknown problem.
When I write my code to test whether the matrix is populated correctly. I only get the first matrix printed and then the program stopped. Output: 1 2 3
4 5 6
Here's the part of the code. Thanks in advance.
int main(){
int **mat1,**mat2,**result;
int row1,col1,row2,col2;
int i,j,k;
FILE *file;
char fname[100];
printf("enter file name\n");
scanf("%s", &fname);
file=fopen(fname, "r");
fscanf(file, "%d %d", &row1,&col1);//row of first matrix
mat1=malloc(row1 * col1 * sizeof(int*));//create memory for first matrix
//reading data for first matrix
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
fscanf(file, "%d", &mat1[i][j]);
}
}
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
printf("%d\t",mat1[i][j]);
}
printf("\n");
}
fscanf(file,"%d %d", &row2, &col2);//row of second matrix
mat2=malloc(row2 * col2 * sizeof(int*));//create memory for second matrix
//reading data for second matrix
for(i=0; i<row2; i++)
{
for(j=0; j<col2; j++)
{
fscanf(file,"%d",&mat2[i][j]);
}
}
for(i=0; i<row2; i++) //check mat2
{
for(j=0; j<col2; j++)
{
printf("%d\t",mat2[i][j]);
}
printf("\n");
}
I think I fixed the problem, but I had to do quite a bit of debugging due to lots of segfaults, so I'll put the answer to the original question at the top and defer all the things I had to debug to the bottom.
fscanf(file, "%*[.]"); //this is to read the period in the file
fscanf(file,"%d %d", &row2, &col2);//row of second matrix
mat2=malloc(row2 * col2 * sizeof(int*));//create memory for second matrix
By adding that one line of code, it started working for me, but it only started working due to the debugging below.
Since the number of calls to malloc did not represent the number of nested ararys that were indexed, I had to change the declaration of the matrices, the way they were populated, and they way they are referenced.
int *mat1,*mat2;
This declaration is to make the next edits work.
//reading data for first matrix
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
fscanf(file, "%d", &(mat1[i*col1 + j]));
}
}
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
printf("%d\t",mat1[i*col1 + j]);
}
printf("\n");
}
And of course, for the second matrix;
//reading data for second matrix
for(i=0; i<row2; i++)
{
for(j=0; j<col2; j++)
{
fscanf(file,"%d",&(mat2[i*col2 + j]));
}
}
for(i=0; i<row2; i++) //check mat2
{
for(j=0; j<col2; j++)
{
printf("%d\t",(mat2[i*col2 + j]));
}
printf("\n");
}
Please keep in mind that if you are going to be referencing an array inside of an an array, then you need to malloc space for another array in each slot of the original array. I chose the unintuitive approach to matrix arithmetic, but the code can be augmented to easily allow for double array indexing to be used.
You have some problem with allocating a 2D arrays:
For example:
mat1=malloc(row1 * col1 * sizeof(int*));//create memory for first matrix
it should be
mat1=(int**)malloc(row1 * sizeof(int*));//create memory for first matrix
Then should allocate each row in mat1 in for loop with before scanf each cell in a matrix
for (i = 0; i < row1; i++)
{
mat1[i] = malloc(col1 * sizeof(int));
for (j = 0; j < col1; j++)
{
fscanf(file, "%d", &mat1[i][j]);
}
}
Then, do similar stuff for mat2
Here is my solution that based on original problem:
#include <stdio.h>
#include <stdlib.h>
int main() {
int **mat1, **mat2, **result;
int row1, col1, row2, col2;
int i, j, k;
FILE *file;
char fname[100];
printf("enter file name\n");
scanf("%s", &fname);
file = fopen(fname, "r");
fscanf(file, "%d %d", &row1, &col1);//row of first matrix
mat1 = (int **)malloc(row1 * sizeof(int*));//create memory for first matrix
//reading data for first matrix
for (i = 0; i < row1; i++)
{
mat1[i] = malloc(col1 * sizeof(int));
for (j = 0; j < col1; j++)
{
fscanf(file, "%d", &mat1[i][j]);
}
}
for (i = 0; i < row1; i++)
{
for (j = 0; j < col1; j++)
{
printf("%d\t", mat1[i][j]);
}
printf("\n");
}
fscanf(file, "%d %d", &row2, &col2);//row of second matrix
mat2 = (int **)malloc(row2 * sizeof(int*));//create memory for second matrix
//reading data for second matrix
for (i = 0; i < row2; i++)
{
mat2[i] = malloc(col2 * sizeof(int));
for (j = 0; j < col2; j++)
{
fscanf(file, "%d", &mat2[i][j]);
}
}
for (i = 0; i < row2; i++) //check mat2
{
for (j = 0; j < col2; j++)
{
printf("%d\t", mat2[i][j]);
}
printf("\n");
}
fclose(file);
return 0;
}
I have a data set with specific format that I want to read in C and also print in certain format. Here is the format of my data in text file:
sample[0][0]=1; sample[0][1]=3;
sample[1][0]=2; sample[1][1]=4;
sample[2][0]=3; sample[2][1]=5;
and I want to read this and return
(*inputs)[0][0] = 1; (*outputs)[0]=3;
(*inputs)[1][0] = 2; (*outputs)[1]=4;
(*inputs)[2][0] = 3; (*outputs)[2]=5;
I was able to write a code that will read my file in just the following format:
1 3
2 4
3 5
and here is my code:
int main() {
FILE *samples;
samples = fopen ("peaks.txt","r");
int arr[10][2];
int i;
int j;
for (i=0; i<10; i++) {
for (j=0; j<2; j++) {
fscanf(samples, "%d, ", &arr[i][j]);
printf("int = %d\t", arr[i][j]);
}
printf("\n");
}
}
How do I modify this code to read the format above? Thank you.
You could read in with, for example for the first line of data,
fscanf(filein, "sample[0][0]=%d; sample[0][1]=%d;", &arr[0][0], &arr[0][1]);
but it is very fragile becaues if the input file is not exactly that then you will get unpredictable behaviour
You could print out with
printf("(*inputs)[0][0] = %d; (*outputs)[0]=%d;", arr[0][0], arr[0][1]);
but probably I got the print statement wrong as I don't know exactly what you want your code to do.
Now for lots of data.....
new version... much simpler...D'oh!
int a,b;
for (i=0; i<10; i++) {
for (j=0; j<2; j++) {
fscanf(samples, "sample[%d][%d]=\%d;", &a, &b, &arr[i][j]);
printf("int = %d\t", arr[i][j]);
}
printf("\n");
}
so now you read in the number values from sample as a and b - but then don't used these value of a and b - though to write a good program you could check the values of a and b are equal to i and j as you expect.
old not working version below
char* string_input[100]; // we need this to get the right format for scanf...
for (i=0; i<10; i++) {
for (j=0; j<2; j++) {
sprintf(string_input, "sample[%d][%d]=\%d;", i, j)
fscanf(samples, string_input, &arr[i][j]);
printf("int = %d\t", arr[i][j]);
}
printf("\n");
}
so what this does is make a taylor made string suitable for reading in your data line by line...
so for example if i=8 and j=1 then string_input will be sample[8][1]=%d;
I first apologize if some of you find my problem stupid and easy to solve, but I am a very beginner in "c".
My task is to create an inverse of a 3x3 matrix using different functions.
What I am trying to do now is to tell the user to input values for the 3x3 matrix and then print them. I made 2 functions which read and print the values, but I have problems with calling them since I cannot directly call an array in printf.
For now I am able to run the program, enter the values and print a wrong result which leads to a not responding program.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3 //defining the size of the matrix (3x3)
//prototyping the functions used to calculate the inverse of the matrix
void readMatrix(double a[SIZE][SIZE]);
void printMatrix(double a[SIZE][SIZE]);
main()
{
double a[SIZE][SIZE];
int i,j;
printf("Enter the values for the matrix:\n", i, j);
readMatrix(a);
printf("Your Matrix:%d\n",a[i][j]);
printMatrix(a);
return 0;
}
//function 1
//letting the user to enter a matrix
void readMatrix(double a[SIZE][SIZE]){
int i,j;
for(i = 0; i < SIZE; i++){
for(j = 0; j < SIZE; j++){
scanf("%d", &a[i][j]);
}
}
}
//function 2
//outputing the given matrix
void printMatrix(double a[SIZE][SIZE]){
int i,j;
for(i = 0; i < SIZE; i++){
for(i = 0; i < SIZE; j++){
printf("Your matrix is: %d", a[i][j]);
}
}
}
In printf and scanf, it is crucial that you pass the exact format specifier that matches the type of the pointer to the variable. If your format specifier doesn't match the supplied argument, the result is undefined behaviour.
In effect, this
scanf("%d", &a[i][j]);
Needs to be replaced with
scanf("%lf", &a[i][j]);
And the same for printf("Your matrix is: %d", a[i][j]); -> printf("Your matrix is: %lf", a[i][j]);
Also, in printMatrix, you've used the loop variable i in the inner loop twice. What you want is
for(i = 0; i < SIZE; i++){
for(j = 0; j < SIZE; j++){
printf("%lf ", a[i][j]);
printf("\n");
}
Edit: As pointed out by #cse in the comments, remove this line in main:
printf("Enter the values for the matrix:\n", i, j);
Since at this point, i, and j are not initialised, they'd contain junk.
in printMatrix, there is a infinite loop which will definitely lead your program to no responding. Should be:
for(j = 0; j < SIZE; j++){
printf("Your matrix is: %d", a[i][j]);
}
For printing the output: you will want to actually print out the entire thing rather than one value after another, correct?
printf ("matrix is:\n")
char outstr[64]; //arbitrary but plenty big enough
char * pout; //points to a point in the string
for(j = 0; j < SIZE; j++){
pout = outstr;
for(i = 0; i < SIZE; i++){
pout += sprintf (pout, "%lf," a [i][j]);
*(--pout) = 0; //end the string one char earlier (dangling ',')
printf ("[%s]\n", outstr);
}
Will print:
matrix is:
[1,2,3]
[4,5,6]
[7,8,9]
Where the numbers are of course the ones in the array.
Also unless you were intending on filling the matrix in a columnar fashion, you should switch the i and j loops on the input function. You are storing the matrix in memory transposed. (This code assumes that you are not)
There are following problems with above code:
In line printf("Your Matrix:%d\n",a[i][j]); of main() function, since variable i and j are not initialized so it contains garbage value. So don't print value at a[i][j] because it may cause of segmentation fault. OR initialize i and j with a valid value i.e. which is a valid index in array double a[][]. Also you can change line printf("Enter the values for the matrix:\n", i, j); in main() to printf("Enter the values for the matrix:\n");. Because i and j are not being used here.
In line scanf("%d", &a[i][j]); of function void readMatrix(double a[SIZE][SIZE]). Since you are reading a double primitive data type then you should use %lf formatter instead of %d. Same for line printf("Your matrix is: %d", a[i][j]) in function void printMatrix(double a[SIZE][SIZE]).
In line for(i = 0; i < SIZE; j++) of function void readMatrix(double a[SIZE][SIZE]). It should be for(j = 0; j < SIZE; j++) i.e. the variable to be used in inner loop should be j not i.
You can find working code here which is after correcting the code.