In the following code, I am trying to read char by char from a file and store each char in a two dimensional array. After that I want to print each char in the array with its coordinates (i and j):
#include <stdio.h>
#pragma warning(disable:4996)
int main(){
char grid[3][5];
FILE *file;
file = fopen("input.txt", "r");
int c;
if (file == NULL){
perror("Error in reading the file");
}
else{
int j=0;
for (int i = 0; i < 3; i++)
{
while (j<5)
{
grid[i][j] = fgetc(file);
j++;
}
j = 0;
}
}
int length = sizeof grid / sizeof grid[0][0];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%c %d %d \n", grid[i][j], i, j);
}
}
printf("\n");
return 0;
}
The file that I read from looks like:
ABCDE
FGHIJ
KLMNO
I want the result to be like:
A 0 0
B 0 1
...
But the real results that I got is:
A 0 0
B 0 1
C 0 2
D 0 3
E 0 4
1 0
F 1 1
G 1 2
H 1 3
I 1 4
J 2 0
2 1
K 2 2
L 2 3
M 2 4
As you can see, the second row is printed with a space first and the same with the third row. Also, the last two letters N and O are not printed. Can someone help me solving this issue?
Change this bit of code
for (int i = 0; i < 3; i++)
{
while (j<5)
{
grid[i][j] = fgetc(file);
j++;
}
j = 0;
}
To add in an if statement which will check to make sure the character it read in is not a newline character \n. The finished code will look like this:
for (int i = 0; i < 3; i++)
{
while (j<5)
{
char c = fegetc(file);
if(c != '\n')
{
grid[i][j] = fgetc(file);
j++;
}
}
j = 0;
}
Fiddling Bits suggested that the inner loop be changed to a for loop (for readability). I would agree, however it does have the drawback of having to put j-- in the else part of the if statement, versus not even needing an else statement. You can view the above fix and this fix with the inner loop changed to a for loop, and decide which one you think has the best readability in this case. This code represents that change as well as the fix for the initial problem:
for (int i = 0; i < 3; i++)
{
for(int j = 0; j < 5; j++)
{
char c = fegetc(file);
if(c != '\n')
{
grid[i][j] = fgetc(file);
} else {
j--;
}
}
}
Try to add another fgetc(file); after the j=0;
(Without any assignment).
It will pull the new line char from your file
Related
I have array and I am trying to print this array as sub blocks, where each block has size = 5.
the out put of this code not as I expected it just print the first 5 values. How to print the array as sub blocks?
int arr[298] = {some int values};
int in = 0;
int siz = 298;
int ii;
int rang = 5;
for (int i = 0; i < siz; i++) {
if (in <= siz) {
for (ii = in; ii < 5; ii++) {
printf("arr=%d \n", arr[ii]);
}
printf("------------\n");
}
ind = ind + rang;
}
Following your request for clarification in the comment section, there are a few problems with your code, for me the biggest one is that it's needlessly complicated, but the one you are looking for is in this line:
ind = ind + rang;
ind is is not declared in your code but I assume you mean in, the first time the inner loop runs in(ind) is 0 so it all goes well, after that in will be 5, you assign it to ii and the condition ii < 5 will never be true again, the body of the loop will never be executed.
I suppose you could fix it by using in as index for the array and scrap rang since it isn't needed, something like this:
int arr[298] = {some int values};
int in = 0;
int siz = 298;
for (int i = 0; i < siz; i++) {
//if (in < siz) { moving this into the for loop
for (int ii = 0; ii < 5 && in < siz; ii++, in++) {
printf("arr=%d \n", arr[in]);
}
printf("------------\n");
//}
}
Live demo: https://godbolt.org/z/YzG9sno1n
But you don't need a nested loop, there are a few ways you can do this, a simple one is to have a variable that controls the block size:
int arr[298] = {some int values};
int siz = 298;
int count = 5;
for (int i = 0; i < siz; i++) {
printf("arr=%d \n", arr[i]);
count--;
if (count == 0) {
printf("------------\n");
count = 5;
}
}
Live demo: https://godbolt.org/z/b4e8vWfhM
In the above code count serves as the control variable, the value in the index is printed 5 times and when it reaches 0 a separator is printed and it resets and starts the new block.
Another possible option is to use the index itself to separate the blocks, you know the remainder of a division is 0 when the numerator is divisible by the denominator, you can use that to your advantage:
int arr[298] = {some int values};
int siz = 298;
for (int i = 0; i < siz; i++) {
if (i % 5 == 0) { // && i != 0 if you want to skip the initial separator
printf("------------\n");
}
printf("arr=%d \n", arr[i]);
}
Live demo : https://godbolt.org/z/nne3z38rY
Finally you can/should use a constant value for size:
#include <stdio.h>
#define SIZE 298
int main() {
int arr[SIZE] = {some int values};
for (int i = 0; i < SIZE; i++) {
if (i % 5 == 0 && i != 0) { // skipping the initial separator
printf("------------\n");
}
printf("arr=%d \n", arr[i]);
}
}
Live demo: https://godbolt.org/z/Mc4Yh4cav
Instead of several for loops, you can use a single while loop.
int arr[298 ]={Some int Values};
int ind =0;
int siz= 298 ;
printf("------------\n");
while(ind<=siz-1){
printf("arr=%d \n",arr[ind]);
ind++;
if(ind%5==0){
printf("------------\n");
}
}
In this, you print the elements through 0 to 297, with a line of dashes printed if the index is divisible by 5, that is after every fifth element.
I have to parse a matrix from a file which first line characters are the rows and the cols count and the next lines are the matrix values.
The file contains:
3 3
R R B
B G G
G B R
I wrote the following code, but it crashes.
char** readMatrix(FILE *file) {
char *array;
int el = 0;
while (fscanf_s(file, "%s", array) != EOF) {
array[el] = array;
el++;
}
const int n = array[0] - '0', m = array[1] - '0';
char** matrix = malloc(n * sizeof(char*));
for (int i = 0; i < n; i++)
{
matrix[i] = malloc(m * sizeof(char));
}
int k = 2;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = array[k];
++k;
}
}
return matrix;
}
The size of the matrix is different for the different files. How is it possible to declare a char array without knowing the size?
First you need to check if your FILE is not NULL ( it may crash cause of this )
if ( file == NULL ) {
printf("Error");
exit(1);
}
Then you need to be sure that your FILE's pointer is pointing at the start of the file :
fseek(file, 0, SEEK_SET);
If your rule is : 'The first line always contains two positive integer separate by a space and ending the line just after the second uint', then you can read them like this :
int dim_x = 0, dim_y = 0 ;
fscanf(file, "%d %d\n", &dim_x, &dim_y);
if(dim_x <= 0 || dim_y <= 0){
printf("Impossible to get correct the correct dimensions");
exit(1);
}
Then you can read your file line by line to have the correct data.
There is many variation to read your file. Assuming that any datas of your file are single characters spaced by 1 space or 1 backline, you can loop like this :
char ** matrix = (char**)malloc(sizeof(char*) * nbr_y);
for(int line = 0 ; line < nbr_y ; line ++){
matrix[line] = (char*)malloc(sizeof(char) * nbr_x);
for(int data_x_index = 0 ; data_x_index < nbr_x ; data_x_index ++){
fscanf(f, "%c", &matrix[line][data_x_index]); //Read and stock the character direclty in the matrix
fseek(f, 1, SEEK_CUR); // Go to the next character to read
}
}
for(int i = 0 ; i < nbr_y ; i ++){
for(int j = 0 ; j < nbr_x ; j ++){
printf("%c ", matrix[i][j]);
}
printf("\n");
}
}
Caution : This version is not checking if the text is well formated and if the dimensions are correct !
I want to output Yay if the matrix doesn't contain the same number on the same row or column otherwise output Nay
this is for my college homework. I already tried to check the column and row in the same loop but the output still not right
#include <stdio.h>
int main()
{
int size;
int flag;
scanf("%d",&size);
char matrix[size][size];
for (int i = 0; i < size; i++)
{
for (int l = 0; l < size; l++)
{
scanf("%s",&matrix[i]);
}
}
for (int j = 0; j < size; j++){
for (int k = 0; k < size; k++){
if(matrix[j] == matrix[j+1] || matrix[j][k]==matrix[j][k+1])
{
flag = 1;
}
else
{
flag = 0;
}
}
}
if (flag == 1)
{
printf("Nay\n");
}
else
{
printf("Yay\n");
}
return 0;
}
I expect to output "Nay" when I input
3
1 2 3
1 2 3
2 1 3
and "Yay" when i input
3
1 2 3
2 3 1
3 1 2
Your matrix is a 2D array and you are referencing it using only a single subscript matrix[index] at several places which returns the address of the row. Index it using both the row and column indices. Try the code below:
{
int size;
int flag;
scanf("%d",&size);
char matrix[size][size];
for (int i = 0; i < size; i++)
{
for (int l = 0; l < size; l++)
{
scanf("%s",&matrix[i][l]);
}
}
for(int j = 0; j < size; j++){
for (int k = 0; j < size; j++){
if(matrix[j][0]== matrix[j][k] || matrix[k][0]==matrix[k][j])
{
flag = 1;
break;
}
else
{
flag = 0;
}
}
}
if (flag == 1)
{
printf("Nay\n");
}
else
{
printf("Yay\n");
}
return 0;
}
Your have a logic problem. Your flag is reset on every element in the matrix and thus only reflects the result of the last check.
In addition, you need a break; in your nested loop. The logic is, if your flag becomes 1, you are sure to say Nay, and you don't want the flag to be reset to 0.
int flag = 0;
for (int i = 0; i != size && !flag; ++i) {
for (int j = 0; j != size; ++j) {
if ( /* detection */ ) {
flag = 1;
break;
}
}
}
if (flag)
printf("Nay\n");
else
printf("Yay\n");
Note: The commented /* detection */ part requires more work. Since it's your homework, you may try it first. You could use a hash table for memorization. Or brutal force to make the program simply work. It seems that your detection only checks for neighboring elements, which is not sufficient to assert that an element is unique in its row or column. Consider
1 2 1
3 4 5
6 7 8
I can't do your homework for you. The following is the brutal-force way you may consider.
The if ( /* detection */ ) part could be if (has_same_element(matrix, i, j)), with a function (pseudo code)
int has_same_element(matrix, row, col)
{
for each element a in matrix's row except matrix[row][col] itself
if (a == matrix[row][col])
return 1
for each element b in matrix's col except matrix[row][col] itself
if (b == matrix[row][col])
return 1
return 0
}
Of course there are smarter ways, like using a hash table, in which case you don't even need the nested loop. For the time being, work out a feasible solution, instead of the best solution.
int main(void)
{
int i,j=0,k; //initialization
char equation[100]; //input is a string (I think?)
int data[3]; //want only 3 numbers to be harvested
printf("Enter an equation: ");
fgets(equation, 100, stdin); //not so sure about fgets()
for (i = 0; i < equation[100]+1; i++) { //main loop which combs through
//"equation" array and attempts
//to find int values and store
while (j <= 2) { //them in "data" array
if (isdigit(equation[i])) {
data[j] = equation[i]
j++;
}
}
if (j == 2) break;
}
for (k = 0; k <= 2; k++) { //this is just to print the results
printf("%d\n", data[k]);
}
return 0;
}
Hello! This is my program for my introductory class in C, I am trying to comb through an array and pluck out the numbers and assign them to another array, which I can then access and manipulate.
However, whenever I run this I get 0 0 0 as my three elements in my "data" array.
I am not sure whether I made an error with my logic or with the array syntax, as I am new to arrays.
Thanks in advance!!! :)
There are a few problems in your code:
for (i = 0; i < equation[100]+1; i++) { should be something like
size_t equ_len = strlen(equation);
for (i = 0; i < equ_len; i++) {
Whatever the input is, the value of equation[100] is uncertain, because char equation[100];, equation only has 100 element, and the last of them is equation[99].
equation[i] = data[j]; should be
data[j] = equation[i];
I suppose you want to store digit in equation to data.
break; should be deleted.
this break; statement will jump out of the while loop, the result is you will store the last digit in equation to data[0] (suppose you have switched data and equation, as pointed out in #2).
If you want the first three digits in equation, you should do something like
equ_len = strlen(equation);
j = 0;
for (i = 0; i < equ_len; i++) {
if (j <= 2 && isdigit(equation[i])) {
data[j] = equation[i];
j++;
}
if (j > 2) break;
}
printf("%d\n", data[k]); should be printf("%c\n", data[k]);
%d will give the ASCII code of data[k], for example, if the value of data[k] is character '1', %d will print 50 (the ASCII code of '1') instead of 1.
Here is my final code, based on the OP code:
#include <ctype.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
int i,j,k;
char equation[100];
int data[3];
int equ_len;
printf("Enter an equation: ");
fgets(equation, 100, stdin);
equ_len = strlen(equation);
j = 0;
for (i = 0; i < equ_len; i++) {
if (j <= 2 && isdigit(equation[i])) {
data[j] = equation[i];
j++;
}
if (j > 2) break;
}
for (k = 0; k <= 2; k++) {
printf("%c\n", data[k]);
}
return 0;
}
Tested with:
$ ./a.out
Enter an equation: 1 + 2 + 3
1
2
3
Need to figure out a code that counts all the repeating symbols in a string. As you can see below, so far so good.
And here starts the tricky part, at the end of the code I want to output symbols in an order they were typed which had for example 2 occurences in a string, and I got problems figuring that out.
int counts[256] = { 0 };
int i;
size = strlen(text);
for (i = 0; i < size; i++) {
counts[(int)(text[i])]++;
}
for (i = 0; i < 256; i++) {
printf("The %d. character has %d occurrences.\n", i, counts[i]);
}
Just iterate through the source string again and for each character look into your counts array.
If you don't want to print the same statistics for every occurence of repeating character, you can reset the corresponding counts value to zero just after you print the statistics, and have an additional check before printing.
for(i = 0; i < size; i++) {
if(counts[(int)(text[i])] == 2)
printf("%d", (int)(text[i]));
The first line loops through your source string for the order of occurences.
The second line checks if it was captured in the counts array as occuring only twice.
If it was we print the char code on the third line.
To only print the character once:
for(i = 0; i < size; i++) {
if(counts[(int)(text[i])] == 2) {
printf("%d", (int)(text[i]));
counts[(int)(text[i])] = 0;
}
}
Here is an implementation of Inspired's answer:
int counts[256] = { 0 };
char text[] = "Hello, world!";
int i, size = strlen(text);
for (i = 0; i < size; i++)
{
counts[(unsigned int)(text[i])]++;
}
for (i = 0; i < size; i++)
{
if (counts[(unsigned int)text[i]] > 1)
{
printf("%c", text[i]);
counts[(unsigned int)text[i]] = 0; // Remove to print repeats.
}
}
Make a key,count pair, like:
#include <string.h>
#include <stdio.h>
int main()
{
char* text = "count this text";
char *keys = new char[strlen(text)];
int* count = new int[strlen(text)];
int last = 0; int j=0;
for(int i=0; i<strlen(text); i++){
for(j=0; j<last; j++){
if(keys[j]==text[i]) break;
}
if(keys[j]==text[i]){
count[j]++;
} else {
keys[last]=text[i];
count[last]=1;
last++;
}
}
for(int i=0; i<last; i++){
printf("%c %d\n", keys[i], count[i]);
}
}
so you keep the order in the text and get the count.
On execution the output is:
c 1
o 1
u 1
n 1
t 4
2
h 1
i 1
s 1
e 1
x 1