The Code exits after the input and output statements - c

After printing the 2nd printf the code exit and says Run Failed and says exit on level 2 ( whatever the input was )
void main()
{
int testcases;
int n_lines ,m_length;
int test, lines, length;
char n_m_matrix[n_lines][m_length];
printf("Enter the no. of Test Cases ");
scanf("%d",&testcases);
printf("%d",testcases);
for(test=0;test>testcases;test++)
{
printf("Enter the lines and length of the test cases ");
scanf("%d%d",&n_lines,&m_length);
for(lines=0;lines<n_lines;lines++)
{
for(length=0;length<m_length;length++)
{
scanf("%c",&n_m_matrix[lines][length]);
}
}
}
}

You need to move the declaration of n_m_matrix into the loop so that it's after you input the variables that hold the dimensions.
As others mentioned, you also have a typo in test > testcases, it should be <.
And you should read an extra character after entering the dimensions, to read the newline. Otherwise it will leave the newline after the dimensions in the input buffer, and this will be read as the first %c input when reading the contents.
You might also consider using fgets() to read each line, instead of doing it character by character. The way you've written it, if there are newlines at the end of each line, they will be inserted into the array. It's not clear whether that's wanted. If it is, make sure you include them in the line length input.
int main()
{
int testcases;
int n_lines ,m_length;
int test, lines, length;
printf("Enter the no. of Test Cases ");
scanf("%d",&testcases);
printf("%d\n",testcases);
for(test=0; test < testcases; test++)
{
printf("Enter the lines and length of the test cases ");
scanf("%d%d",&n_lines,&m_length);
getc(); // Skip over the newline
char n_m_matrix[n_lines][m_length];
for(lines=0;lines<n_lines;lines++)
{
for(length=0;length<m_length;length++)
{
scanf("%c",&n_m_matrix[lines][length]);
}
}
}
}

To clear confusion among the serveral problem the first one which invokes Undefined behavior in the code is, using uninitialized variable as VLA's size.
Also the for loop logic is wrong and character input might create some problem the way it is handled. (when entered with \n).
Correct code would be (considering that you don't want the whitespaces inputted into the array. Because if you do then there are other better choices like fgets etc).
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 1024
int main(void)
{
int testcases;
int n_lines ,m_length;
int test, lines, length;
printf("Enter the no. of Test Cases ");
if( scanf("%d",&testcases) != 1){
fprintf(stderr, "%s\n","Error in input" );
exit(1);
}
if( testcases <= 0 ){
fprintf(stderr,"%s\n","Enter nonzero integer for testcases");
exit(1);
}
printf("%d",testcases);
for(test = 0; test < testcases; test++)
{
printf("Enter the lines and length of the test cases ");
if(scanf("%d%d",&n_lines,&m_length)!=1){
fprintf(stderr, "%s\n","Error in input" );
exit(1);
}
if( n_lines <= 0 || m_length <= 0 || !(n_lines <= MAXSIZE && m_length <= MAXSIZE)){
fprintf(stderr, "%s\n","Error in input n_lines and m_length" );
exit(1);
}
char n_m_matrix[n_lines][m_length];
for(lines = 0; lines < n_lines; lines++)
{
for(length = 0; length < m_length; length++)
{
if( scanf(" %c",&n_m_matrix[lines][length]) != 1)
{
fprintf(stderr, "%s\n","Eror in input" );
exit(1);
}
}
}
// work with VLA here.
}
return 0;
}
Here if you need much larger array sizes than this go for dynamic memory allocation. That will satisfy larger memory requirement in array.

You need to use dynamic memory allocation, malloc method. The matrix n_m_matrix dimension is dynamically decided based on user input.
Allocate memory to n_m_matrix using malloc
In for loop correct logical error test>testcase to test<testcase
Put below code out of for loop
printf("Enter the lines and length of the test cases ");
scanf("%d%d",&n_lines,&m_length);

Related

Using the Scanf function for inputs for different lengths

I want to use the scanf function to get inputs that are either two numbers, or one number from the user and put them in an array. However, I'm not sure how I can use this same function to get inputs for both one element of the array, and also two elements of the array.
i.e. if the user enters, 9 0, it should be able to successfully store that in an array and move onto new code, or if the user enters something like 1, it should also be able to successfully store that in the array, and move onto new code.
I've tried putting the scanf into a while loop:
int scanned_array[2] = {};
int element = 0;
while(scanf("%d", &scanned_array[element]) {
//... more code here which will have different functions depending on the input...
element++;
}
How can I successfully do this while only using the scanf function, while loops, arrays and if statements?
**Edit: Just wondering, if I changed my code according to what was suggested below by #nmgari, how could I go to if(num == 1) { ... without having to press ctrl+d?
Thanks for reading!
If i understand correctly you want to call scanf() once and read either one number or two.
Something like this should work:
int scanned_array[2];
int num_input = 0;
num_input = scanf("%d %d", &scanned_array[0], &scanned_array[1]);
if(num_input == 1)
{
//Do something
}
else if (num_input == 2)
{
//Do somethine else
}
Anyway, you need to consider that the second element in the array may never get a value.
You should read the input line with fgets() and parse it with sscanf():
char buf[120];
if (fgets(buf, sizeof buf, stdin)) {
int i1, i2;
switch (sscanf(buf, "%d%d", &i1, &i2)) {
case 2:
/* the user entered 2 integers */
handle_2_integers(i1, i2);
break;
case 1:
/* the user entered a single integer */
handle_1_integer(i1);
break;
default:
/* the user did not enter a number */
handle_invalid_input();
break;
}
} else {
/* the input stream is at end of file or encountered an error */
handle_end_of_file();
}
If you run scanf("%d%d", &i1, &i2), scanf() will keep reading the input stream until either end of file, or 2 integers have been read or an character has been input that cannot be converted to an integer, possibly reading multiples lines of input for one of these cases to occur. If you want to handle a single line of input, you cannot use scanf() directly.
A separate scan for whitespace could be used.
The scanset %1[ \t\r\n] will capture whitespace character by character. The loop will exit on non-whitespace or a newline.
Then try to scan an integer.
#include <stdio.h>
#include <stdlib.h>
int main ( void) {
char space[2] = "";
int scanned = 0;
int scanned_array[2] = { 0};
while ( 1) {
while ( 1 == scanf ( "%1[ \t\r\n]", space)) {
if ( '\n' == space[0]) {
break;
}
}
if ( '\n' == space[0]) {
break;
}
if ( 1 != scanf ( "%d", &scanned_array[scanned])) {
fprintf ( stderr, "bad input\n");
return 1;
}
++scanned;
if ( 2 <= scanned) {
break;
}
}
for ( int each = 0; each < scanned; ++each) {
printf ( "%d\n", scanned_array[each]);
}
return 0;
}

Reading string of number from terminal and save in an array in c

I am trying to implement bubble sort in C. The question has a constraint that:
The first line should be the number of elements in the array
The second line is the input
For example:
first line: 5
second line: 5 4 2 8 1
I need to read the second line an storing it into an array to be able to sort them. I have searched on the internet and found that getline() helps us to read a line. The issue here is that if I want to use getline() I need to know how many bits are going to read so I can allocate enough space for it, but here we do not know how along a number would be.
The code I have written is as follow:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv){
int sizeOfArray;
// getting the number of inputs from the second line.
// Then go to the third line
scanf("[^\n]%d[^\n]", &sizeOfArray);
int inputArray[sizeOfArray];
//------------------------------------
// This bit I have stuck. I do not know how to solve it
for(int iteration = 0; iteration<sizeOfArray; iteration++)
{
("%d ", &inputArray[iteration]);
}
// ----------------------------
int arrSizeCopy = sizeOfArray;
int mediator = 0 ;
while(arrSizeCopy> 0)
{
for(int i=0; i< arrSizeCopy-1; i++)
{
if(inputArray[i]>inputArray[i+1])
{
mediator = inputArray[i];
inputArray[i] = inputArray[i+1];
inputArray[i+1] = mediator;
}
}
arrSizeCopy--;
}
for (int i=0; i<sizeOfArray; i++)
{
printf("%d ", inputArray[i]);
}
return 0;
}
I really appreciate if someone could help me to find the answer for it.
this is from the getline man page, and it looks to answer your concerns
"If *lineptr is set to NULL and *n is set 0 before the call, then
getline() will allocate a buffer for storing the line. This buffer
should be freed by the user program even if getline() failed.
Alternatively, before calling getline(), *lineptr can contain a
pointer to a malloc(3)-allocated buffer *n bytes in size. If the
buffer is not large enough to hold the line, getline() resizes it
with realloc(3), updating *lineptr and *n as necessary."
http://man7.org/linux/man-pages/man3/getline.3.html
This line
scanf("[^\n]%d[^\n]", &sizeOfArray);
seems a bit strange.
So I changed your code like
if (scanf("[^\n]%d[^\n]", &sizeOfArray) != 1)
{
printf("Bad luck\n");
return;
}
and gave it the input you describe, i.e. 5. The result was Bad luck So the scanf failed and sizeOfArray is uninitialized (which is very bad).
Instead simply try
if (scanf("%d", &sizeOfArray) != 1)
{
printf("Bad luck\n");
exit(1);
}
and you'll see it work.
Also change
scanf("%d ", &inputArray[iteration]);
into
if (scanf("%d", &inputArray[iteration]) != 1)
{
printf("Bad luck\n");
exit(1);
}
When using scanf you shall always check the return value.
A complete example for reading and printing data:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
int sizeOfArray;
if (scanf("%d", &sizeOfArray) != 1)
{
printf("Bad luck\n");
exit(1);
}
int inputArray[sizeOfArray];
for(int iteration = 0; iteration<sizeOfArray; iteration++)
{
if (scanf("%d", &inputArray[iteration]) != 1)
{
printf("Bad luck\n");
exit(1);
}
}
for (int i=0; i<sizeOfArray; i++)
{
printf("%d ", inputArray[i]);
}
return 0;
}
Input:
5
1 2 3 4 5
Output:
1 2 3 4 5

Replacing `goto` with a different programming construct

I m trying to do this little programm with defensive programming but its more than difficult for me to handle this avoiding the Loop-Goto as i know that as BAD programming. I had try with while and do...while loop but in one case i dont have problem. Problem begins when i m going to make another do...while for the second case ("Not insert space or click enter button"). I tried and nested do...while but here the results was more complicated.
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i;
int length;
char giventext [25];
Loop:
printf("String must have 25 chars lenght:\n");
gets(giventext);
length = strlen(giventext);
if (length > 25) {
printf("\nString has over %d chars.\nMust give a shorter string\n", length);
goto Loop;
}
/* Here i trying to not give space or nothing*/
if (length < 1) {
printf("You dont give anything as a string.\n");
goto Loop;
} else {
printf("Your string has %d\n",length);
printf("Letter in lower case are: \n");
for (i = 0; i < length; i++) {
if (islower(giventext[i])) {
printf("%c",giventext[i]);
}
}
}
return 0;
}
Note that your code is not defensive at all. You have no way to avoid a buffer overflow because,
you check for the length of the string after it has been input to your program so after the buffer overflow has already occurred and
you used gets() which doesn't check input length and thus is very prone to buffer overflow.
Use fgets() instead and just discard extra characters.
I think you need to understand that strlen() doesn't count the number of characters of input but instead the number of characters in a string.
If you want to ensure that there are less than N characters inserted then
int
readinput(char *const buffer, int maxlen)
{
int count;
int next;
fputc('>', stdout);
fputc(' ', stdout);
count = 0;
while ((next = fgetc(stdin)) && (next != EOF) && (next != '\n')) {
// We need space for the terminating '\0';
if (count == maxlen - 1) {
// Discard extra characters before returning
// read until EOF or '\n' is found
while ((next = fgetc(stdin)) && (next != EOF) && (next != '\n'))
;
return -1;
}
buffer[count++] = next;
}
buffer[count] = '\0';
return count;
}
int
main(void)
{
char string[8];
int result;
while ((result = readinput(string, (int) sizeof(string))) == -1) {
fprintf(stderr, "you cannot input more than `%d' characters\n",
(int) sizeof(string) - 1);
}
fprintf(stdout, "accepted `%s' (%d)\n", string, result);
}
Note that by using a function, the flow control of this program is clear and simple. That's precisely why goto is discouraged, not because it's an evil thing but instead because it can be misused like you did.
Try using functions that label logical steps that your program needs to execute:
char * user_input() - returns an input from the user as a pointer to a char (using something other than get()! For example, look at scanf)
bool validate_input(char * str_input) - takes the user input from the above function and performs checks, such as validate the length is between 1 and 25 characters.
str_to_lower(char * str_input) - if validate_input() returns true you can then call this function and pass it the user input. The body of this function can then print the user input back to console in lower case. You could use the standard library function tolower() here to lower case each character.
The body of your main function will then be much simpler and perform a logical series of steps that tackle your problem. This is the essence of defensive programming - modularising your problem into separate steps that are self contained and easily testable.
A possible structure for the main function could be:
char * user_input();
bool validate_input(char *);
void str_to_lower(char *);
int main()
{
char * str_input = user_input();
//continue to get input from the user until it satisfies the requirements of 'validate_input()'
while(!validate_input(str_input)) {
str_input = user_input();
}
//user input now satisfied 'validate_input' so lower case and print it
str_to_lower(str_input);
return 0;
}

Am I using strncmp and fgets in the right way?

I'm a beginner programmer trying to learn C. Currently I'm taking a class and had a project assigned which I managed to finish pretty quickly, at least the main part of it. I had some trouble coding around the main() if functions though, because I started using some new functions (that is, fgets and strncmp). Now, my code works in my compiler, but not in any of the online compilers. So I'm wondering if I did something wrong with it, or if there is any way I can improve it.
Any help or contribution is appreciated, thanks!
Below is the code, the encrypt and decrypt functions are the first two functions before the main, where I believe most of the messy shortcut-code might be.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * Encrypt(char sentence[])
{
int primes[12] = {1,2,3,5,7,11,13,17,19,23,29,31};
int x = 0;
int counter = 0;
int ispositive = 1;
while(sentence[x] != 0)
{
if (counter == 0)
{
ispositive = 1;
}
else if(counter == 11)
{
ispositive = 0;
}
if (ispositive == 1)
{
sentence[x] = sentence[x] + primes[counter];
counter++;
}
else if (ispositive == 0)
{
sentence[x] = sentence[x] + primes[counter];
counter--;
}
x++;
}
return sentence;
}
char * Decrypt(char sentence[])
{
int primes[12] = {1,2,3,5,7,11,13,17,19,23,29,31};
int x = 0;
int counter = 0;
int ispositive = 1;
while(sentence[x] != 0)
{
if (counter == 0)
{
ispositive = 1;
}
else if(counter == 11)
{
ispositive = 0;
}
if (ispositive == 1)
{
sentence[x] = sentence[x] - primes[counter];
counter++;
}
else if (ispositive == 0)
{
sentence[x] = sentence[x] - primes[counter];
counter--;
}
x++;
}
return sentence;
}
int main()
{
char message[100];
char input[7];
char *p;
int c;
int condition = 1;
while(condition == 1)
{
printf("Would you like to Encrypt or Decrypt a message? (Type TurnOff to end the program) \n \n");
fgets(input,7, stdin);
fflush(stdin);
if (!strncmp(input,"Encrypt",strlen(input)))
{
printf("\n \n Enter the message you want to Encrypt below: \n \n");
fgets(message, 100, stdin);
Encrypt(message);
printf("\n Your encrypted message is: ");
printf("%s", message);
fflush(stdin);
printf("\n \n");
}
else if (!strncmp(input,"Decrypt",strlen(input)))
{
printf("\n \n Enter the message you want to Decrypt below: \n \n");
fgets(message, 100, stdin);
Decrypt(message);
printf("\n Your Decrypted message is: ");
printf("%s", message);
fflush(stdin);
printf("\n \n");
}
else if (!strncmp(input,"TurnOff",strlen(input)))
{
printf("\n \n Thank you for using the program! \n \n");
condition = 0;
}
else
{
printf("That's not a valid input \n \n");
}
}
}
After the printf you doing fflush(stdin) instead of you have to do fflush(stdout). Because you are printing the output. The output is printed in stdout. So, you have to flush the stdout buffer not stdin buffer.
You can use the strcmp instead of strncmp. Because in here you are comparing the hole character in the input array. So, the strcmp is enough.
strcmp(input, "Encrypt").
The strcmp or strncmp function get the input in array upto a null or the size of the string you are declared.
The size for the input array is too few.
lets take the input is like below.
Encrypt\n
sureshkumar\n
In here you first fgets in main function reads the upto "Encrypt" it does not skip the '\n'.
The '\n' is readed form another fgets. So, it does not get the encrypt message "sureshkumar".
So, you have to modify you code. You will increase the size for the input array.
And check the condition like below.
if(strcmp(input, "Encrypt\n") == 0)
{
/*
You will do what you want
*/
}
You can use the above way or you can read the input and overwrite the '\n' to '\0' in the input array and compare as it is you before done. But you have to use the strcmp. Because the array size is incremented.
This is the right way for using the fgets. Use of fgets is to read upto new line.
You have to use the null character for the character array. Because this is necessary for the character arrays.
Your initiative towards using strcmp() and fgets() is good, though, it requires following understanding:
1. fgets() writes atmost size-1 characters into buffer and then terminates with '\0'. In your case,
fgets(input,7, stdin);
You gave input "Encrypt"/"Decrypt"/"TurnOff"
but
'input' buffer got data as "Encryp"/"Decryp"/"TurnOf"
because of size=7 (only (7-1)=6 characters being read, last position reserved for '\0' character by fgets()).
Your strncmp() calls will work correctly with your current code, since for strncmp(), length to compare
n = strlen(input) = 6;
6 characters are matching fine in all three cases of "Encrypt"/"Decrypt"/"TurnOff".
Summary is that your current code will work fine, But your actual intention is violated. You actually wanted to read and compare full length of option string.
EDIT DONE : Modifications suggested:
#define SIZE 9 <-- EDIT : Change done here, instead of 7, size = 9 is used
to allow reading '\n' so that it does not affect
fgets() read in successive iteration
char input[SIZE];
fgets(input, SIZE, stdin); // read str is e.g. "Encrypt\n"
input[SIZE-2] = '\0'; // To replace '\n' with '\0'
Similarly, you need to be careful when reading into 'message' array using fgets().

fgets, sscanf, and writing to arrays

beginner question here, I haven't been able to find examples that relate. I'm working on a C program that will take integer input from stdin using fgets and sscanf, and then write it to an array. However, I'm not sure how to make fgets write to the array.
#define MAXINT 512
char input[MAXINT]
int main(void)
{
int i;
int j;
int count=0;
int retval;
while (1==1) {
fgets(input, MAXINT[count], stdin);
retval = sscanf(input, "%d", &i);
if (retval == 1) {
count = count++;
}
else
if (retval != 1) {
break;
}
}
Would I simply put fgets in a for loop? or is it more complicated than that?
fgets() reads into a string (array of char), not an array of int.
Your loop should be:
char line[4096];
while (fgets(line, sizeof(line), stdin) != 0)
{
...code using sscanf() iteratively to read into the array of int...
}
Not checking inputs leads to problems. At best, your code would process the last line of input twice, most likely. You're only allowed to do that if it means that my refund gets processed twice. At worst, your code might never terminate until your program gets bored to death, or runs out of memory, or you lose patience with it and kill it.
[This] doesn't answer the question of how I would write to the array within the while loop. Would I enclose the sscanf function in a for loop for however many numbers got entered? Would I set something up to run each time Enter is pressed?
Given that you only have one number per line, then the code in the body of the loop is simple:
char line[4096];
int array[1024];
int i = 0;
while (fgets(line, sizeof(line), stdin) != 0)
{
if (i >= 1024)
break; // ...too many numbers for array...
if (sscanf(line, "%d", &array[i++]) != 1)
...report error and return/exit...
}
Note that this code won't notice if there is garbage (other numbers, non-numbers) on the same line; it simply grabs the first number (if there is one) and ignores the rest.
If you need multiple numbers per line, look at How to use sscanf() in loops for more information.
If you want a blank line to terminate the input, then using fscanf() or scanf() is not an option; they read through multiple blank lines looking for input.
One can put fgets() & ssprintf() in one long condition:
#define MAXINT 512 /* suggest alternate name like Array_Size */
int input[MAXINT];
char buf[100];
int count = 0;
while ((NULL != fgets(buf, sizeof buf, stdin)) && (1 == sscanf(buf,"%d",&input[count]))) {
if (++count >= MAXINT) break;
}
... or something a bit more user friendly:
// While stdin not closed and input is more than an "Enter" ...
while ((NULL != fgets(buf, sizeof buf, stdin)) && (buf[0] != '\n')) {
if (1 != sscanf(buf,"%d",&input[count])) {
puts("Input was not an integer, try again.\n");
continue;
}
if (++count >= MAXINT) break;
}
Using sscanf is easy, but put into array ...
C is hard to dynamic init array in terms of size, this sometimes massacre perfectionists.
int main()
{
int total_n;
int n;
int i;
char *s = "yourpattern1yourpattern2yourpattern23";
printf("your string => %s\n", s);
int array[129] = {0};//some big enough number to hold the match
int count = 0;
while (1 == sscanf(s + total_n, "%*[^0123456789]%d%n", &i, &n))
{
total_n += n;
printf("your match => %d\n", i);
array[count] = i;
count++;
}
printf("your array => \n");
for (i=0;i<count;i++)
printf("array[i] => %d\n", array[i]);
}
and the output
[root#localhost ~]# ./a.out
your string => yourpattern1yourpattern2yourpattern23
your match => 1
your match => 2
your match => 23
your array =>
array[i] => 1
array[i] => 2
array[i] => 23

Resources