Get several characters lines into an array in c - c

for an uni assignment I have to do the following: https://ibb.co/5WpMS0V (I cant upload a photo, the server is messed up or something)
What I've got so far is the following: Im trying to get all the characters that I need to put in, into an array but it's not working properly. Can anyone explain to me how to do this? Also, the subject this week is recursion, so I should make this with the use of recursion. If anyone knows how to get the characters in properly, then I know how to move on! Thanks in advance.
// libraries
#include <stdio.h> // endables input/output commands
#include <stdlib.h> // enables standard library of functions
// main
int main(int argc, char *argv[]) {
int numberOfRows;
int numberOfColoms;
scanf("%d %d", &numberOfRows,&numberOfColoms);
char matrix[numberOfRows][numberOfColoms];
char letter = getchar();
scanf("%c" , &letter);
do {
for (int i = 0; i < numberOfRows; i++) {
for (int j = 0; j < numberOfColoms; j++) {
scanf("%c" , &matrix[i][j]);
}
}
} while (letter != '\n');
for (int i = 0; i < numberOfRows; i++) {
for (int j = 0; j < numberOfColoms; j++) {
printf("%c" , matrix[i][j]);
}
}
return 0;
}

The letter variable and the do .. while loop are unnecessary. You just need to read rows * cols characters.
Use " %c" with scanf to skip leading whitespace when reading a character. This will have the effect of ignoring the newlines that separate each line of input.
Remember to check the return value of scanf, which is the number of successful conversions, so that you do not operate on bad data.
Consider limiting the values of rows and cols to an appropriate range. Currently negative or excessively large values will have adverse effects.
Note that the use of recursion is likely expected for the rest of the task (solving the word search), not populating your matrix.
Keep in mind, the contents of matrix are not strings - they are not null-terminated. Use of <string.h> functions and similar will surely lead to undefined behaviour.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int rows;
int cols;
if (2 != scanf("%d %d", &rows, &cols)) {
fprintf(stderr, "Failed to read rows and columns.\n");
return EXIT_FAILURE;
}
char matrix[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (1 != scanf(" %c" , &matrix[i][j])) {
fprintf(stderr, "Unexpected end of valid input.\n");
return EXIT_FAILURE;
}
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%c" , matrix[i][j]);
}
putchar('\n');
}
}

Related

Input for 2D character array in C

I am new to C programming....we have 2D arrays for integers...but how to declare and take the input for 2D string arrays...I tried it for taking single character input at a time similar to integer array...but I want to take whole string as input at a time into 2D array..
code:
#include <stdio.h>
int main()
{
char str[20][20];
int i, j;
for (i = 0; i < 20; i++)
{
for (j = 0; j < 20; j++)
{
scanf("%c", &str[i][j]);
}
}
}
can anyone resolve this problem?
The declaration of a 2D string array can be described as:
char string[m][n];
where m is the row size and n is the column size.
If you want to take m strings as input with one whole string at a time...it is as follows
#include<stdio.h>
int main()
{
char str[20][20];
int i,j;
for(i=0;i<m;i++)
{
gets(str[i]);
}
}
here 'i' is the index of the string....
Hope this answer helps...
A few issues with your code. Using scanf to reach characters, you're going to read newlines. If I create a more minimal version of your code with an extra few lines to print the input, we can see this:
#include <stdio.h>
int main() {
char str[3][3];
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
scanf("%c", &str[i][j]);
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("%c ", str[i][j]);
}
printf("\n");
}
}
And running it:
$ ./a.out
gud
ghu
ert
g u d
g h
u
e
$
We can test the input to circumvent this. If the character input is a newline character ('\n') then we'll decrement j so effectively we've sent the loop back a step. We could easily extend this boolean condition to ignore other whitespace characters like ' ' or '\t'.
#include <stdio.h>
int main() {
char str[3][3];
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
char temp = 0;
scanf("%c", &temp);
if (temp == '\n' || temp == ' ' || temp == '\t') {
j--;
}
else {
str[i][j] = temp;
}
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("%c ", str[i][j]);
}
printf("\n");
}
}
Now,, when we run this:
$ ./a.out
gud
ghu
ert
g u d
g h u
e r t
$
Of course, one other thing you should do is to check the return value of scanf, which is an int representing the number of items read. In this case, if it returned 0, we'd know it hadn't read anything. In that case, within the inner loop, we'd probably also want to decrement j so the loop continues.
#include<stdio.h>
main()
{
char name[5][25];
int i;
//Input String
for(i=0;i<5;i++)
{
printf("Enter a string %d: ",i+1);
}
//Displaying strings
printf("String in Array:\n");
for(int i=0;i<5;i++)
puts(name[i]);
}
Simple code that accepts String in an array.

I keep getting a sementation fault when compiling and running my code

I know it means that there is a problem with trying to access restricted memory but I do not know how to find where the error is occurring or how I would go about fixing it. An small explanation would be very helpful.
int main(int argc, char* argv[1]) {
char emptyBoard[3][3];
char player;
int row, column; // moves
int i, j;
// int x = 0;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
emptyBoard[i][j] = '.';
}
}
/*
for(i = 0; i < 3; i++){
for (j = 0; j < 3; j++){
printf("%c ", emptyBoard[i][j]);
}
printf("\n");
}
*/
FILE* filePtr = fopen(argv[1], "r");
if (filePtr == NULL) {
printf("Cannot open File \n");
return 1;
}
while (fscanf(filePtr, "%c, %d, %d", &player, &row, &column) != EOF) {
// moves = x++;
emptyBoard[row][column] = player;
printBoard(emptyBoard);
}
// printf("Total Moves: %d", moves );
fclose(filePtr);
}
void printBoard() {
int i, j;
char array[3][3];
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("%c ", array[i][j]);
}
printf("\n");
}
}
I know this isn't what you asked for, but I noticed you're passing a variable to printBoard in printBoard(emptyBoard), but the function does not actually take any arguments. What will be printed here is a 'random' collection of values.
As for what you asked, do you pass any arguments to your executable? If it's titled 'run' for example, do you type ./run file.txt or just ./run? If you are doing the latter, that will cause a Segmentation fault because you are trying to load in a value that was not allocated to the argv. Allan is also correct, if the file you are loading calls higher row or column than 3, segmentation fault occurs because you are trying to access memory that you did not allocate to emptyBoard.
As to finding the cause of runtime errors, I have found placing print statements at the different steps of my program to be quite helpful. You could learn to use a debugger.
The program crash if row or column in input file is >= 3.
The fscanf condition is not sufficient to terminate the loop either check on number of records have been processed or add space so scanf eats the trailing newline:
while (fscanf(filePtr, "%c, %d, %d ", &player, &row, &column)) != EOF) {
You call printBoard(emptyBoard) but it's defined as not taking any arguments, and you create a local array. Try this instead:
void printBoard(size_t row, size_t column, char array[row][column]) {
int i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
printf("%c ", array[i][j]);
}
printf("\n");
}
}
...
printBoard(3, 3, emptyBoard);
This will result in players being accumulated. If you want one player per board, then you need to either initialize the board or operate on a copy of empty board:
char board[3][3];
memcpy(board, emptyBoard, sizeof(emptyBoard);
board[row][column] = player;
printBoard(3, 3, board);

To printf a matrix

When i want to print a matrix which i input,i can use code:
#include <stdio.h>
int main(void)
{
int n, m; //row and column
printf("Enter row and column:\n");
scanf("%d %d", &n, &m);
int x[n][m];
printf("Enter your matrix:\n");
for (int i = 0; i < n; i++) //input my matrix
{
for (int j = 0; j < m; j++)
{
scanf("%d", &x[i][j]);
}
}
printf("print it:\n");
for (int i = 0; i < n; i++) //print it
{
for (int j = 0; j < m; j++)
{
printf("%d ", x[i][j]);
}
putchar('\n');
}
}
enter image description here(a possible case)
In code above, I have to assign values to the rows and columns of the matrix,which named "n" and "m".
int n, m;
scanf("%d %d", &n, &m);
But now I am asking a way to automatic tally .
Can I get this one directly?
enter image description here
You can simulate a two-dimensional array with a one-dimensional array, if that's what you mean:
#include <stdio.h>
#include <stdlib.h>
#define DIGITS 3
int main(void) { // It's good practice to fill function arguments with void if not planning on using them
/* scanf("%d %d", &n, &m); Using scanf with uninitialised variables will result in
* undefined behaviour if it is unable to convert the input. Using fgets
* is easier to debug, safer, and cleaner.
* I highly recommend this: http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
*/
char buf[DIGITS+1];
printf("%s", "Enter array rows:");
fgets(buf, DIGITS+1, stdin);
const int n = atoi(buf);
printf("%s", "Enter array columns:");
fgets(buf, DIGITS+1, stdin);
const int m = atoi(buf);
int x[n*m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("Enter array value at %d, %d: ", i, j);
fgets(buf, DIGITS+1, stdin);
x[i+j] = atoi(buf);
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%d ", x[i+j]);
}
printf("\n");
}
}
I'm not really sure as to why you would do this when C supports your two-dimensional array answer equally.
But now I am asking a way to automatic tally. Can I get this one directly?
Yes.
Form a linked-list of lines. Initially the list is empty.
Read the first line of input, the "1 2 3" into a string. Use fgets().
Parse the line to detect the number of values in it.
Append the line to the linked list of lines.
Continue doing so until 1) end-of-file, 2) a blank line or 3) number of integer is not the same as the first (error condition).
Now code has the m (number of values per line) and n, the number of lines.
Form int x[n][m];
Parse the lines for values and save in x.

I'm having a hard time understanding the process for populating a multidimensional array. Why does my code print the one letter multiple times?

I was having a problem with this part while doing one of my assignments. So I decided to do a simple program to store and see if my understanding is correct but I am still having the same problems.
Initially, I didn't make the arrays pointers but that caused the program to crash immediately. So that is also why they are char pointers. If anyone can also explain why they need to be pointers and why it prints the way it does, that would be immensely helpful.
#include <stdio.h>
int main() {
char arr[2][2];
char str[20];
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("%s\n", "please put in a string: ");
scanf("%s\n", str[0]);
arr[i][j] = str[0];
}
}
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("arr[%d][%d] == %s\n", i,j,arr[i][j]);
}
}
return 0;
}
the output that i got:
please put in a string:
pleasework
what
please put in a string:
s
please put in a string:
f
please put in a string:
g
arr[0][0] == f
arr[0][1] == f
arr[1][0] == f
arr[1][1] == f
Not the right outputs
If you want to just learn about:
"I'm having a hard time understanding the process for populating a multidimensional array."
then forget the string and the char, and do something simple, like use an int. The following code sample shows exactly that.
Simplest case: Populate multi-dim array of any type
#include <stdio.h>
int main() {
int arr[2][2];
int str;
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("please put in a number [%d][%d]: ", i,j);
scanf("%d", &str);
arr[i][j] = str;
}
}
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("arr[%d][%d] == %d\n", i,j,arr[i][j]);
}
}
return 0;
}
$ ./stackoverflow
please put in an number[0][0]: 1
please put in an number[0][1]: 2
please put in an number[1][0]: 34
please put in an number[1][1]: 450
arr[0][0] == 1
arr[0][1] == 2
arr[1][0] == 34
arr[1][1] == 450
Populate chars
If you want to use single characters, then you can use the following code also, BUT you have to take care. scanf works in mysterious ways. Notice how the space is there before the %c. That is to consume the \n that is there you press enter. You can read up here, but that was the reason for why you had to initially enter twice somet input and press enter. Frankly, I would use something else than scanf like fgets maybe, but since you used scanf, I showed the code which uses it also.
#include <stdio.h>
int main() {
char arr[2][2];
char str;
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("%s", "please put in a character: ");
if (scanf(" %c", &str) == 1) { arr[i][j] = str; }
}
}
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("arr[%d][%d] == %c\n", i,j,arr[i][j]);
}
}
return 0;
}
$ ./stackoverflow
please put in a character: a
please put in a character: b
please put in a character: c
please put in a character: d
arr[0][0] == a
arr[0][1] == b
arr[1][0] == c
arr[1][1] == d
Populate Strings
If you want to read strings, then you need to do it a little differently. You need not a 2 dimensional array. You need a 3-dimensional array because the strings are themselves char-arrays. Without a 3D-array you overwrote the 2D array and only got the last value printed multiple times. What was worse, since your multidimensional array is 2x2 while the input string is 1xn, and where n was greater than 2, you would have gotten buffer overflow. The following code fixes these.
#include <stdio.h>
#include <string.h>
int main() {
char arr[2][2][20];
char str[20];
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("%s", "please put in a string: ");
if (scanf("%s", &str[0]) == 1)
{
// arr[i][j] = &str[0];
strncpy(arr[i][j], str, 20);
}
}
}
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("arr[%d][%d] == %s\n", i,j, arr[i][j]);
}
}
return 0;
}
$ ./stackoverflow
please put in a string: ab
please put in a string: cd
please put in a string: ef
please put in a string: gh
arr[0][0] == ab
arr[0][1] == cd
arr[1][0] == ef
arr[1][1] == gh
And just for good measure, here is the 4th variation, which uses char* arr[2][2] instead of a 3D-char array. It doesn't change much, but like I said, just for good measure.
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main() {
char* arr[2][2];
char str[20];
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("%s", "please put in a string: ");
if (scanf("%s", &str[0]) == 1)
{
arr[i][j] = (char*)malloc(20*sizeof(char));
strncpy(arr[i][j], str, 20);
}
}
}
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("arr[%d][%d] == %s\n", i,j, arr[i][j]);
}
}
return 0;
}

Read matrix from input in C without <iostream> features

In C++, I can read a matrix with something like
int main()
{
int i,j,k,n;
float a[10][10]={0},d;
clrscr();
cout<<"No of equations ? "; cin>>n;
cout<<"Read all coefficients of matrix with b matrix too "<<endl;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>a[i][j];
...
return 0;}
in C I cannot use
#include <iostream>
and related functions as
- clrscr();
- cout<<
- cin>>
How should I fix my code to work in c?
For simple cases like this, using scanf() is not rocket science:
if (scanf("%d", &n) != 1)
…report unexpected EOF or format error…
if (n > 10)
…report that n is too big…
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (scanf("%f", &a[i][j]) != 1)
…report unexpected EOF or format error…
Use %f because a is an array of float. Check that you got a value each time you try to read one. You can capture the return from scanf() if you want to distinguish between (premature) EOF and format error.
OTOH, in more complex scenarios, scanf() is extremely hard to use correctly. Use with caution. Consider using fgets() or
getline() along with
sscanf(); it is often easier to control the input handling and usually improves the error reporting.
Here you go:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int n, i, j;
double **M;
// prompt the user to enter number of equations
printf("Enter # of equations:");
if (scanf("%d", &n) != 1 && n > 0) exit(1);
// allocate square n x n matrix
M = (double**) malloc(sizeof(double*) * n);
for (i = 0; i < n; ++i) M[i] = (double*)malloc(sizeof(double)* n);
// prompt user to enter matrix coefficients
printf("Read all coefficients of matrix with b matrix too\n");
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
if (scanf("%lf", &(M[i][j])) != 1) exit(1);
}
}
// print values of matrix
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
printf("%lf ", M[i][j]);
}
printf("\n");
}
// free allocated memory
for (i = 0; i < n; ++i) {
free(M[i]);
}
free(M);
return 0;
}

Resources