When I run this program with a file imported into Xcode, I receive an error of Thread 1: EXC_BAD_ACCESS (code=1 address=0x68) at the line c = fgetc(ptr);. I am not sure why fptr is null when it gets to this line. Any help would be great thanks.
#include <stdio.h>
#define M 100
#define N 100
char array[M][N] = {0};
void readFile();
void findStartandEnd();
void mazeTraversal();
int m = 0;
int n = 0;
int start[2] = {0};
int end[2] = {0};
int main() {
readFile();
//findStartandEnd();
//mazeTraversal();
}
void readFile() {
FILE *fptr;
char c;
char file_name[20];
int i, j;
printf("Please enter the size of the MxN maze.\n");
printf("Start with the M size then the N size follow each number by the return key.\n");
scanf("%d", &m);
scanf("%d", &n);
printf("Type in the name of the file containing the Field\n");
scanf("%s", file_name);
fptr = fopen(file_name, "r");
for (i = 0; i < M && i < m; i++)
for (j = 0; j < N && j < n; j++) {
c = fgetc(fptr);
while (!((c == '1') || (c =='0')))
c = fgetc(fptr);
array[i][j] = c;
}
fclose(fptr);
for (i = 0; i < M && i < m; i++)
for (j = 0; j < N && j < n; j++) {
if (j == 0) printf("\n");
printf("%c ", array[i][j]);
}
printf("\n");
}
You do not test if scanf correctly parsed a string into file_name. You do not even protect file_name from a potential buffer overflow with scanf("%19s", file_name);
Furthermore, you do not test whether fopen succeeded at opening the file. fptr could be NULL for many possible reasons, you must test that and fail gracefully.
Note that scanf will stop at the first white space character after the first word. Filenames with embedded spaces cannot be entered with this method.
Note also that c should be defined as int instead of char to properly test for end of file as EOF returned by fgetc() does not fit in a char.
You should also use braces around non trivial statements commended by the for loops. They are not strictly necessary, but it will avoid silly bugs when later amending your code.
Related
problem
After receiving the string S, write a program that repeats each character R times to create a new string and print it out. That is, you can make P by repeating the first character R times and repeating the second character R times. S contains only the QR Code "alphanumeric" characters.
QR Code "alphanumeric" character is 0123456789ABCDEFGHIJK
Input
The number T (1 ≤ T ≤ 1,000) of test cases is given in the first line. Each test case is given by dividing the number of repetitions R (1 RR 88) and the string S into spaces. The length of S is at least 1 and does not exceed 20 characters.
Output
Output P for each test case.
input Example
2
3 ABC
5 /HTP
output Example
AAABBBCCC
/////HHHHHTTTTTPPPPP
My code:
#include<stdio.h>
int main() {
int a=0;
scanf("%d", &a);
for (int k = 0; k < a; k++) {
int d;
char b[20];
scanf("%d", &d);
scanf("%s", &b);
for (int i = 0; b[i]!=NULL; i++) {
for (int j = 0; j < d; j++) {
printf("%c", b[i]);
}
}
}
}
There is a problem in the code:
scanf("%s", b);
we write "b" instead of "&b"
‘&’ is used to get the address of the variable. C does not have a string type, String is just an array of characters and an array variable stores the address of the first index location.By default the variable itself points to the base address and therefore to access base address of string, there is no need of adding an extra ‘&’
so we can write :
#include<stdio.h>
int main() {
int a=0;
scanf("%d", &a);
for (int k = 0; k < a; k++) {
int d;
scanf("%d", &d);
char b[20];
scanf("%s",b);
for (int i = 0; b[i]; i++) {
for (int j = 0; j < d; j++) {
printf("%c", b[i]);
}
}
printf("\n");
}
}
Improvements
Use size_t to iterate through arrays
NOTE: char b[20];, b decays to pointer (sizeof() operator is an exception)
In line scanf("%s", &b);, &b is not required it will cause undefined behavior, just b is fine
Always check whether scanf() input was successful
Don't use "%s", use "%<WIDTH>s", to avoid buffer-overflow
b[i]!=NULL is quite wrong, NULL is a pointer whereas b[i] is a char, and char can't be compared with pointer, you should check for '\0' or just 0
Initialize your variable b using = {}, then all the elements of b will be 0
Length of b should be 21 +1 for the null terminating character
Final Code
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a = 0;
if (scanf("%d", &a) != 1) {
fputs("bad input", stderr);
return EXIT_FAILURE;
}
for (int k = 0; k < a; k++) {
int d;
if (scanf("%d", &d) != 1) {
fputs("bad input", stderr);
return EXIT_FAILURE;
}
char b[21] = {};
if (scanf("%20s", b) != 1) {
fputs("bad input", stderr);
return EXIT_FAILURE;
}
for (size_t i = 0; b[i] != 0; i++) {
for (int j = 0; j < d; j++) {
printf("%c", b[i]);
}
}
puts("\n");
}
return EXIT_SUCCESS;
}
Input
2
3 ABC
5 /HTP
Output
AAABBBCCC
/////HHHHHTTTTTPPPPP
TRY IT ONLINE
The problem is my code doesn't execute the for loop. It's just taking one input and printing it.
#include<stdio.h>
int main(){
int A[100], B[100], C[100], D[100];
int r[100];
for(int i = 0; i < 3; i++)
{
scanf("(%d+%d)x(%d-%d)", &A[i], &B[i], &C[i], &D[i]);
r[i] = (A[i]+B[i])*(C[i]-D[i]);
}
for(int k = 0; k < 3; k++)
{
printf("%d", r[k]);
}
return 0;
}
Assuming you input expressions are separated by a newline, when the second call to scanf is made, the first unread character is a newline rather than a left parenthesis. To make scanf skip leading whitespace characters, start the format string with a space, i.e. " (%d+%d)x(%d-%d)".
https://pubs.opengroup.org/onlinepubs/000095399/functions/fscanf.html
First a fall this is the wrong way to use scanf.
use the below code:-
#include<stdio.h>
int main(){
int A[100], B[100], C[100], D[100];
int r[100];
for(int i = 0; i < 3; i++)
{
scanf("%d %d %d %d", &A[i], &B[i], &C[i], &D[i]);
r[i] = (A[i]+B[i])*(C[i]-D[i]);
}
for(int k = 0; k < 3; k++)
printf("%d", r[k]);
return 0;
}
The problem is you do not skip the pending newline when reading the second line of input, so the newline does not match ( and scanf() returns 0.
You should always test scanf() return value to ensure input was validly converted.
Also make sure each result is printed as a separate number by appending a space or a newline.
Here is a modified version:
#include <stdio.h>
int main() {
int A[100], B[100], C[100], D[100];
int r[100];
int n = 0;
for (int i = 0; i < 3;) {
/* ignore pending spaces */
if (scanf(" (%d+%d)x(%d-%d)", &A[i], &B[i], &C[i], &D[i]) == 4) {
r[i] = (A[i] + B[i]) * (C[i] - D[i]);
n = ++i;
} else {
int c;
/* flush pending input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF)
break;
printf("Invalid input, try again:");
}
}
for (int k = 0; k < n; k++) {
printf("%d\n", r[k]);
}
return 0;
}
i fixed it with Add a space before the first ( inside the scanf " (%d+%d)x(%d-%d)"
i want to create a dynamic matix to enter a character , so i start firstly with creating a dynamic matric of int to after switch it to char
the code of the dynamic matrix works correctly :`
#include <stdio.h>
#include <stdlib.h>
int main(){
int r , c , b;
int *ptr, count = 0, i;
printf("ROWS ");
scanf("%d",&r);
printf("COLS ");
scanf("%d",&c);
ptr = (int *)malloc((r * c) * sizeof(int));
for (i = 0; i < r * c; i++)
{
scanf("%d",&b);
ptr[i] = b;
}
for (i = 0; i < r * c; i++)
{
printf("%d ", ptr[i]);
if ((i + 1) % c == 0)
{
printf("\n");
}
}
return 0;}
but when i did this change to switch it to matrix of char it doesn't read all the charecter so it stopped reading before the matrix finish
#include <stdio.h>
#include <stdlib.h>
int main()
{
int r , c ;
int count = 0, i;
char *ptr,b;
printf("ROWS ");
scanf("%d",&r);
printf("COLS ");
scanf("%d",&c);
ptr = (char *)malloc((r * c) * sizeof(char));
for (i = 0; i < r * c; i++)
{
scanf("%c",&b);
ptr[i] = b;
}
for (i = 0; i < r * c; i++)
{
printf("%c ", ptr[i]);
if ((i + 1) % c == 0)
{
printf("\n");
}
}
return 0;
}
It seems you need to write
scanf(" %c",&b);
^^^^
to skip white space characters including the new line character '\n' that corresponds to the pressed Enter key.
That is when the format string starts from the space character white space characters are skipped.
Pay attention to that you should free the allocated memory when the dynamically allocated array is not needed any more.
Otherwise if you want to read also spaces in the array then you can rewrite the for loop the following way
for (i = 0; i < r * c; i++)
{
do scanf("%c",&b); while ( b == '\n' );
ptr[i] = b;
}
so I can't seem to redirect an input so that my program reads it.
It says in the assignment that the program should NOT print anything to prompt for user input. As many numbers have to be read from stdin to test your programs, you are expected to use INPUT REDIRECTION to read the input from a file.
I have this main function:
int main(int argc, char const *argv[])
{
int arr[100];
for (int i = 0; i < SIZE; i++)
{
values[i] = 0;
hashMapLinear[i] = 0;
}
FILE* file = fopen("file_name.txt", "r");
int index = 0;
int k = 0;
while (!feof(file))
{
fscanf(file, "%d", &k);
arr[index] = k;
index++;
}
fclose(file);
file = fopen("file_name.txt", "r");
int i = 0;
fscanf(file, "%d", &i);
float size = i;
fscanf(file, "%d", &i);
int thresh_hold = i;
int load_factor = size / 2;
int j = 0;
if (size <= 0)
{
printf("\nSize of file can not be zero or negative integer:\n");
}
else
{
while (!feof(file))
{
if (num_keys <= load_factor)
{
int check_valid_input= fscanf(file, "%d", &i);
if (check_valid_input != 0 || check_valid_input== -1)
{
insert_into_hashtable(i, size);
}
else
{
printf("\n invalid input:\n");
exit(1);
}
}
else
{
printf("\nError in inserting more numbers:\n");
exit(1);
}
}
fclose(file);
printHashMap(arr,size, thresh_hold);
}
}
How do I edit this main function so that it redirects seq.1 or any other text file to the C program? Any help would be appreciated!
Simply use stdin instead of file, but do not open stdin, and do not close it.
When calling a program like ./program < seq.1, the operating system will pass the content of seq.1 to your program as if it were inputed through the console. Hence, using stdin, which represents console input, will do the job.
Note that stdin is by default already opened when your program starts.
Your code is hardcoding the input file, so file redirection from the command line will not do anything. File redirection helps with stdin (console input), stdout (console output), and stderr (console error message output). See linuxcommand.org here for a tutorial.
So to make your code work with stdin, use scanf instead of fscanf. scanf takes input from FILE stdin, whereas fscanf takes input from a specified FILE. Using scanf will result in input from stdin, which can be redirected on the command line as described above. Similarly, if you want to use stdout, use printf instead of fprintf. Neither scanf or printf take a file parameter, but are the same as fscanf and fprint in other respects. See this stackOverflow article for some more explanation.
Here is how I would fix your code to read/write to stdin and stdout:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int arr[400];
for (int i = 0; i < SIZE_HASH_MAP; i++)
{
values[i] = 0;
hashMapLinear[i] = 0;
}
// Not Needed: FILE* file = fopen("file_name.txt", "r");
int index = 0;
int k = 0;
while (!feof(stdin))
{
scanf("%d", &k);
arr[index] = k;
index++;
}
// fclose(file);
// file = fopen("file_name.txt", "r");
int i = 0;
scanf("%d", &i);
float size = i;
//printf("%d ", i);
scanf("%d", &i);
int thresh_hold = i;
//printf("%d ", i);
int load_factor = size / 2;
int j = 0;
//int check_valid_input = 0;
if (size <= 0)
{
printf("\nSize of file can not be zero or negative integer:\n");
}
else
{
while (!feof(stdin))
{
if (num_keys <= load_factor)
{
int check_valid_input= scanf("%d", &i);
if (check_valid_input != 0 || check_valid_input== -1)
{
insert_into_hashtable(i, size);
}
else
{
printf("\n invalid input:\n");
exit(1);
}
}
else
{
printf("\nError in inserting more numbers:\n");
exit(1);
}
}
// fclose(file);
printHashMap(arr,size, thresh_hold);
}
}
To use stdin (and file redirection), you will not be able to close and reopen stdin and get the same data. It just does not work that way. So remove one of the read loops so you only read it once. The first loop reads it into array arr[], so the second loop should take the values from that array rather than re-reading it.
#include <stdio.h>
$include <stdlib.h>
int main(int argc, char const *argv[])
{
int arr[400];
for (int i = 0; i < SIZE_HASH_MAP; i++)
{
values [i] = 0;
hashMapLinear[i] = 0;
}
int index = 0;
int k = 0;
while (!feof(stdin))
{
scanf("%d", &k);
arr[index] = k;
index++;
}
float size = arr[0];
int thresh_hold = arr[1];
int load_factor = size / 2;
int j = 0;
if (size <= 0)
{
printf("\nSize of file can not be zero or negative integer:\n");
exit(-1);
}
else
{
int i;
for(i=2; i<index; i++) // reuse values stored in arr[]
insert_into_hashtable(arr[i], size);
printHashMap(arr,size, thresh_hold);
}
}
You may want to use open() instead of fopen(). Open returns a non-negative integer representing the lowest numbered unused file descriptor. With file descriptors it is much easier to redirect your output.
The shell command already redirects input to your program. There is a file pointer called stdin already opened in your program that represents the standard input. When you use < seq.1, it pipes the contents of the file in the standard input of your program, which you can read using fgetc or scanf.
int main(int argc, char const *argv[])
{
int arr[400];
for (int i = 0; i < SIZE_HASH_MAP; i++)
{
values[i] = 0;
hashMapLinear[i] = 0;
}
int index = 0;
int k = 0;
while (!feof(stdin))
{
fscanf(stdin, "%d", &k);
arr[index] = k;
index++;
}
}
This program reads all the numbers from the standard input and stores them in your array. Notice you don't need to open or close it, it is already open when your main is called and closed at the end of your program execution.
hey so i m trying to read numbers from text file and put them into an array but ive been getting weird numbers when i try to print them. text file looks like:
45
77
8
...
i guess theres something wrong with the loop i m using but i cant seem to find out what.
thanks for your help!
code:
#define MAX_ARRAY_SIZE 20
int main(int argc, char * argv[])
{
FILE *myFile;
int myArray[MAX_ARRAY_SIZE];
//char filename[32];
//printf("enter filename\n");
//scanf("%s", filename);
myFile = fopen("asdf.txt", "r");
if (!myFile) {
printf("cant open file\n");
return 1;
}
int status;
int i = 0;
while ((status = fscanf(myFile, "%2d", &myArray[i])) == 1 && i < MAX_ARRAY_SIZE - 1) {
++i;
}
fclose(myFile);
int a;
for (a = 0; i < MAX_ARRAY_SIZE; ++i) {
printf("%d ", myArray[i]);
}
printf("\n");
return 0;
}
The problem is in your print loop:
for (a = 0; i < MAX_ARRAY_SIZE; ++i)
There is no guarantee you are reading MAX_ARRAY_SIZE values. Also, if you ar using 'a' as your loop iterator, then you need to use 'a'. Your loop should be:
for (a = 0; a < i; ++a)
printf("%d ", myArray[a]);
You also do not need a field-width in your format-specifier, fscanf(myFile, " %d", &myArray[i])) will do.
Try this
while ((status = fscanf(myFile, "%d\n", &myArray[i])) == 1 && i < MAX_ARRAY_SIZE - 1) {
++i;
}
True... I have not seen print loop code.. Sorry.
Problem is in print loop not fscan, please ignore my answer