What's wrong with this simple C code? - c

#include <stdio.h>
int main()
{
int m,n; scanf("%d %d",&m,&n);
char ar[m][n];
char buf[n];
int a,b;
for(a=0;a<m;a++)
{
gets(buf);
for(b=0;b<n;b++) ar[a][b] = buf[b];
}
for(a=0;a<m;a++,printf("\n")) for(b=0;b<n;b++) printf("%c",ar[a][b]);
return 0;
}
This code takes m lines as input from stdin, each line containing n characters, and prints all the lines to stdout. Simple as that. But there seems to be a memory leak, because the first time gets(buf) is encountered, its execution is skipped.
I tried it in C++ too, thinking the memory leak will disappear. Here is the code:
#include <cstdio>
using namespace std;
int main()
{
int m,n; scanf("%d %d",&m,&n);
char **ar = new char*[m];
char *buf = new char[n];
int a,b;
for(a=0;a<m;a++)
{
gets(buf);
ar[a] = new char[n];
for(b=0;b<n;b++) ar[a][b] = buf[b];
}
for(a=0;a<m;a++,printf("\n")) for(b=0;b<n;b++) printf("%c",ar[a][b]);
return 0;
}
But it is behaving exactly the same.
Here is some sample input and output:
2 3
abc
def
output:
x��
abc
GDB doesn't seem to show anything up too. Please help..

It's not a "memory leak". The problem is that the first gets() call reads the newline from when you enter the two dimensions on the first line; it puts zero characters into the buffer, but you print 5, which is why you get a line of garbage.
Add a "\n" at the end of the scanf() format string so scanf() consumes the newline, and your program will work perfectly. Note that gets() is terribly unsafe; using fgets(buf, n, stdin) is much preferred.

In addition to missing '\n' in scanf() you should allocate more space for buf:
Example
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m,n;
if(scanf("%d%d\n",&m,&n) != 2)
exit(EXIT_FAILURE);
char ar[m][n];
char buf[n+2]; // '\n\0'
int a,b;
for(a=0;a<m;a++)
{
if (!fgets(buf, n+2, stdin)) exit(EXIT_FAILURE);
for(b=0;b<n;b++) ar[a][b] = buf[b];
}
for(a=0;a<m;a++,printf("\n")) for(b=0;b<n;b++) printf("%c",ar[a][b]);
return 0;
}
Output
abc
def

Related

Print a string till a particular character comes

I want the string to be printed till character ('e') comes.
Code which I tried:-
#include <stdio.h>
int main() {
int a,i,x;
char b[10];
char ch;
//enter input string
for(i=0;i<10;i++)
scanf("%c",&b[i]);
for(i=0;i<10;i++)
if(b[i]!='e')
printf("%c",b[i]);
return 0;
}
Input:abcdefghij
Actual output:abcdfghij
Desired output:abcd
Question : Where am I wrong ? Will putting a break inside if block work here?
This is much cleaner if you want to use scanf.
#include <stdio.h>
int main()
{
char b[101];
scanf("%100s", b);
printf("%s\n", b);
return(0);
}
Or even better.
#include <stdio.h>
#define MAX_LENGTH 100
int main()
{
char b[MAX_LENGTH+1]; // add 1 for the terminating zero
scanf("%100s", b);
printf("%s\n", b);
return(0);
}
This one uses fgets to read the entire line.
#include <stdio.h>
#define MAX_LENGTH 100
int main()
{
char b[MAX_LENGTH];
fgets(b, MAX_LENGTH, stdin);
printf("%s", b);
return(0);
}
How to print a string till limit?
What code should do is use fgets().
Avoid using scanf(). Is is too easy to use wrong.
#include <stdio.h>
#include <string.h>
int main() {
char b[100];
if (fgets(b, sizeof b, stdin)) {
// If code needs to lop off the potential \n at the end
b[strcspn(b, "\n")] = '\0';
printf("%s\n", b);
}
return 0;
}
Advanced issues include how to handle excessively long input lines and error handling - not shown here.
Here is what you need to do
#include <stdio.h>
int main()
{
int a,i,x;
char b[10];
char ch;
//enter input string
for(i=0;i<10;i++)
{
scanf("%c",&b[i]);
}
for(i=0;i<10;i++)
{
if(b[i]=='e')
{
break;
}
}
return 0;
}
re
There are several mistakes!
If you are initializing your loops from 0 then you need to set the condition till i<100.
Change your format specifiers to %s.
Change your IF statement to if(b[i]!='\0').
#include <stdio.h>
int main()
{
int i;
char b[10];
for(i=0;i<10;i++)
{
scanf("%c",&b[i]);
}
for(i=0;i<10;i++)
{
if(b[i]=='e')
{
break;
}
printf("%c",b[i]);
}
return 0;
}

C: Program skips next input

My program skips the next input after 1 pass through it. I have read the threads on removing the newline character that fgets has, but nothing that was suggested worked. Is there anything that would work with microsoft visual studio? The best suggestion was "words[strcspn(words, "\r\n")] = 0;" and this did not remove the new line, unless I am formatting it incorrectly. I am not allowed to use the strtok function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 50
#define STOP "quit\n"
char *copywords(char *dest, const char *source, size_t n);
int main(void)
{
char words[50];
char newwords[50];
size_t num;
for (;;) {
printf("\nType a word, or type 'quit' to quit: ");
(fgets(words, SIZE, stdin));
if (strcmp(words, STOP) == 0) {
printf("Good bye!\n");
return 0;
}
printf("Type the # of chars to copy: ");
scanf_s("%d", &num);
copywords(newwords, words, num);
printf("The word was %s\n", words);
printf("and the copied word is %s", newwords);
}
}
char *copywords(char *dest, const char *source, size_t n) {
size_t i;
for (i = 0; i < n && source[i] != '\0'; i++) {
dest[i] = source[i];
}
dest[i] = '\0';
return dest;
}
The problem is that you leave the \n on the input when you call scanf. i.e. the user types number[return]. You read the number. When you loop around and call fgets agains the return is still waiting to be read so thats what fgets gets and it returns immediately.
I would probably just call fgets the second time you want to read input as well and then use sscanf to read from the string. i.e.
printf("Type the # of chars to copy: ");
fgets(buffer, ...)
sscanf(buffer, "%d", ...)
As an aside I would also say to check return values as it is easy for fgets or *scanf to fail.
My program skips the next input after 1 pass through it.
If I understand you correctly, the problem is that scanf_s (which I assume is like the C standard's scanf) will read the digits into num, but scanf won't remove the following newline from stdin, and so in the next iteration of the loop fgets will see that newline and behave as if it had seen a blank line.
I have usually avoided scanf for this reason and instead read a line into a buffer and then parse it. For example:
char buf[50];
...
fgets(buf,sizeof(buf),stdin);
sscanf(buf,"%d",&num);
(I'd also recommend adding a whole lot more error checking throughout.)
Here's a straightforward solution.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 50
#define STOP "quit\n"
char *copywords(char *dest, const char *source, size_t n);
int main(void)
{
char words[50];
char newwords[50];
size_t num, run = 0;
for (;;) {
printf("\nType a word, or type 'quit' to quit: ");
if(run)
getchar();
(fgets(words, SIZE, stdin));
if (strcmp(words, STOP) == 0) {
printf("Good bye!\n");
return 0;
}
printf("Type the # of chars to copy: ");
scanf("%d", &num);
copywords(newwords, words, num);
printf("The word was %s\n", words);
printf("and the copied word is %s", newwords);
run = 1;
}
}
char *copywords(char *dest, const char *source, size_t n) {
size_t i;
for (i = 0; i < n && source[i] != '\0'; i++) {
dest[i] = source[i];
}
dest[i] = '\0';
return dest;
}
Since we know there will be an extra '\n' character left in the stream due to the scanf, just take it out.

unable to take two input strings in C on Ubuntu

I am unable to take two inputs strings simultaneously in C on Ubuntu. It shows the wrong output.
Simple program:
#include <stdio.h>
main()
{
char s1[20],char s2[20],printf("\nEnter job:");
scanf("%[^\n]s",s1);
printf("Enter hobby:");
scanf("%[^\n]s",s2);
}
Output:
Enter job:student
Enter hobby:
student
It does not allow the input of a second string. How can I overcome this bug?
If you want to allow embedded spaces, modify the scanf formats this way:
#include <stdio.h>
int main(void) {
char job[100], hobby[100];
printf("Enter job:");
scanf("%99[^\n]%*c", job);
printf("Enter hobby:");
scanf("%99[^\n]%*c", hobby);
printf("%s,%s", job, hobby);
return 0;
}
But be aware that empty lines will not be accepted by this scanf format. The linefeed will stay in the input stream, the second scanf will fail too and job and/or hobby will have indeterminate contents, letting printf invoke undefined behavior.
Is is much more reliable to use fgets() and strip the '\n'.
#include <stdio.h>
#include <string.h>
int main(void) {
char job[100], hobby[100];
printf("Enter job:");
if (!fgets(job, sizeof job, stdin))
return 1;
job[strcspn(job, "\n")] = '\0';
printf("Enter hobby:");
if (!fgets(hobby, sizeof hobby, stdin))
return 1;
hobby[strcspn(hobby, "\n")] = '\0';
printf("%s,%s", job, hobby);
return 0;
}

c program not taking input properly and producding wrong output

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
int t,n,x,i,j;
char st[50];
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d %d",&n,&x);
for(j=0;j<n;j++)
{
scanf("%c",&st[j]);
if(st[j]=='A')
x=x*1;
if(st[j]=='B')
x=x*-1;
}
printf("%d",x);
}
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
return 0;
}
Input to the code is in the form:
t
n x
some_string_having_A_and_B
Sample:
1
3 10
ABA
expected output
-10
actual output
10
This code gives -10 if number of B is odd and 10 if number of B is even. I know the correct and optimal way of writing the program but I can't figure out, why this code is producing wrong ouput.
The first scanf("%c") reads the previous ENTER in the input stream.
Suggestion for fast fix: use a space inside the specification to have scanf ignore whitespace (Enter is whitespace).
Try
if (scanf(" %c", &st[j]) != 1) /* error */;
// ^ ignore whitespace
Suggestion for better fix: read all user input with fgets().
char line[100];
...
fgets(line, sizeof line, stdin);
if (sscanf(line, "%c", &st[j]) != 1) /* error */;
if(st[j]=='B')
x=x*-1;// you need to put bracket here.on -1
//correct form is x=x*(-1)
}
//corrected code starts from here
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
int t,n,x,i,j;
char st[50];
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d %d",&n,&x);
for(j=0;j<n;j++)
{
scanf("%c",&st[j]);
if(st[j]=='A')
x=x*1;
if(st[j]=='B')
x=x*(-1);// you need to put bracket here.on -1
}
printf("%d",x);
}
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
return 0;
}

scanf not recognises %59[^\n]

Hello all what i am trying to do is to scanf a string to 2 struct variables but when running the code it simply passes though the scanf (both of them) and goes to the printf.
My code is the following:
struct s_Especialidade{
char nome[60];
char descricao[60];
struct s_Especialidade *proximo;
};
typedef struct s_Especialidade Especialidade;
typedef Especialidade *PESPECIALIDADE;
void novaEspecialidade()
{
PESPECIALIDADE novo = malloc(sizeof(Especialidade) );
int opcao=0;
printf("\nNome: ");
scanf("%59[^\n]\n", (novo->nome));
printf("\nDescricao: ");
scanf("%59[^\n]\n", (novo->descricao));
novo->proximo = NULL;
printf("\n%s - %s",novo->nome, novo->descricao);
}
The trouble is that white space (including newlines) in scanf() format strings behaves peculiarly — it means an arbitrary sequence of white space characters.
When it prompts Nome:, you can type a name ('Alexander the Great') and a newline, but the scanf() keeps reading until it comes across another character that isn't white space. So, you might type 'Conqueror of Asia', and then the prompt Descricao: will appear, and it will read until you type another character that isn't white space, and then it will terminate.
For example:
$ ./name-prompt
Nome: Alexander The Great
Conqueror of Asia
Descricao: a
<<Alexander The Great>> - <<Conqueror of Asia>>
$
This is from the code:
#include <stdio.h>
#include <stdlib.h>
struct s_Especialidade{
char nome[60];
char descricao[60];
struct s_Especialidade *proximo;
};
typedef struct s_Especialidade Especialidade;
typedef Especialidade *PESPECIALIDADE;
static
void novaEspecialidade(void)
{
PESPECIALIDADE novo = malloc(sizeof(Especialidade) );
printf("\nNome: ");
if (scanf("%59[^\n]\n", (novo->nome)) != 1)
printf("Oh, bother!\n");
printf("\nDescricao: ");
if (scanf("%59[^\n]\n", (novo->descricao)) != 1)
printf("Oh, bother!\n");
novo->proximo = NULL;
printf("\n<<%s>> - <<%s>>\n", novo->nome, novo->descricao);
free(novo);
}
int main(void)
{
novaEspecialidade();
return 0;
}
Note that the printf() output ends with a newline; that's generally a good idea.
To work around this, modify the scanf() format to:
"%59[^\n]"
After the scanf(), do the equivalent of:
int c;
while ((c = getchar()) != EOF && c != '\n')
;
Package it into a function — maybe gobble() or read_to_newline().
Or use fgets() to read the line and sscanf() to parse it; that often works better.
Are you trying to read 60 characters and indicating that by 59 in the scanf statement? Then, your scanf is wrong. Change it to: scanf ( "%s", novo->nome ); and it should work. Same with the other scanf.
Here is a complete example, reading two strings from stdin, then using sscanf to remove the trailing newline and printing them:
#include <stdio.h>
struct {
char first[60];
char second[60];
} store;
int main(int argc, char ** argv) {
char buffer[60];
printf("write something: ");
fgets(buffer, 60, stdin);
sscanf(buffer, "%s", store.first);
printf("write something else: ");
fgets(buffer, 60, stdin);
sscanf(buffer, "%s", store.second);
printf("you wrote: %s then %s\n", store.first, store.second);
return 0;
}

Resources