I'm writing a program that asks the number of strings which i'll then count how many spaces it has.
My problem is when I start a new cycle I can't allocate the array of characters I use to count the spaces.
Thanks in advance.
#include <stdio.h>
#include <string.h>
int main(){
char a[20];
int x, z, esp=0, num;
scanf("%d\n", &num);
int array[num];
for (int i=0;i<num;i++){
scanf("%[^\n]", &a);
z =strlen(a);
for (x=0; x<=z; x++){
if (a[x] == ' '){
esp++;
}
}
array[i] = esp;
esp =0;
}
for (int i=0;i<num;i++){
printf ("%d\n", array[i]);
}
return 0;
}
Problems:
Not having all warnings enabled. Save time, enable them all.
'\n' blocks for more input in scanf("%d\n", &num);
Not checking scanf() return value.
Not limiting input with a width in scanf("%[^\n]", &a);
Wrong type passed in scanf("%[^\n]", &a);
Big one: not consuming the end-of-line with repeated scanf("%[^\n]", &a); calls.
Perhaps more.
Repaired code:
// scanf("%d\n", &num);
if (scanf("%d", &num) != 1) { // '\n' removed
puts("Error1");
return -1;
}
// scanf("%[^\n]", &a);
if (scanf(" %19[^\n]", a) != 1) { // ' ' consumes white-space like \n
puts("Error2");
return -1;
}
On the first scanf, remove \n character, after the first scanf, add getchar() to consume new line character.
Replace second scanf with gets;
Then it will work correctly.
By the way, since gets is unsafe, you can use fgets with stdin parameter and max character count parameter instead of gets.
Thanks to everyone who commented and answered my question, I think I wasn't able to explain myself properly. It's a code which reads a number, the number of the lines of characters which then it'll count the spaces of; my problem started when the code executes a new cycle in which this scanf didn't let me enter the string of characters again: scanf("%[^\n]", &a), but did everything else in the cycle while using the same string.
I'm really new to this, coding and the page itself so thanks for the advices. I was able to find a solution: scanf("%[^\n]%*c, &a)
%*[^\n] scans everything until a \n, but doesn't scan in the \n. The asterisk(*) tells it to discard whatever was scanned.
%*c scans a single character, which will be the \n left over by %*[^\n] in this case. The asterisk instructs scanf to discard the scanned character.
And here is the updated code:
#include <stdio.h>
#include <string.h>
int main(){
char a[20];
int x, z, esp=0, num;
scanf("%d\n", &num);
int array[num];
for (int i=0;i<num;i++){
scanf("%[^\n]%*c", &a);
z =strlen(a);
for (x=0; x<=z; x++){
if (a[x] == ' '){
esp++;
}
}
array[i] = esp;
esp =0;
}
for (int i=0;i<num;i++){
printf ("%d\n", array[i]);
}
return 0;
}
Related
I am attaching the code for the same.Its working fine.But once i enter a number less than the previous one it stops giving desired output.Any help/suggestion shall be greatly appreciated.
int i=1;
int j=0;
int n;
char ch;
while(ch!='n')
{
printf("Enter the number upto which you want the sum of \n \n");
scanf("%d",&n);
while(i<=n)
{
j=j+i;
i++;
}
printf("%d \n",j);
printf("Do it with another number? Y/N \n \n");
scanf("%s",&ch);
}
return 0;
In your outer while loop, you're never resetting the value of the variable i back to 1, or j back to 0. That is why subsequent loops will produce an incorrect sum.
There are a smattering of bugs in this code, including:
Comparison to uninitialized value of of ch in the initial while expression.
Failing to reset i and j for each outer-loop iteration
Failing to test for data-read success in either scanf call to ensure proper input.
The continuation scanf("%s", &ch) is simply wrong for a single character with skipped whitespace (which you must do to avoid reading the newline after your list integer input). Unless EOF or an error state is reached, what you have now is guaranteed to invoke undefined behavior, as a string-read of at least one character requires at least two for storage (the character, and a subsequent terminator).
Addressing all of those:
#include <stdio.h>
int main()
{
char ch;
do
{
int n;
printf("Enter the number upto which you want the sum of \n \n");
if (scanf("%d", &n) != 1) // See (3)
break;
int j = 0; // See (2)
for (int i = 1; i <= n; ++i) // See (2)
j += i;
printf("%d \n", j);
printf("Do it with another number? Y/N \n \n");
if (scanf(" %c", &ch) != 1) // See (3) and (4)
break;
} while (ch != 'n' && ch != 'N'); // See (1)
return 0;
}
Everything here is self-explanatory when referred to the previous bug punch list, save for maybe the format string for reading the single character. You mentioned in comments that you tried %c but it skipped to another loop iteration. That's because you didn't have the leading whitespace " %c" that tells scanf to skip white space before extracting the next argument. With that, it should work as desired.
You need to reset i and j for every n.
i = 1;j=0;
while(i<=n)
{
Also your format specifer is wrong. For char, it should be %c and not %s
scanf("%c",&ch);
The simplest solution is to set i to 0 at the outer while:
int i=1;
int j=0;
int n;
char ch;
while(ch!='n')
{
i = 0;
printf("Enter the number upto which you want the sum of \n \n");
scanf("%d",&n);
while(i<n)
{
j=j+i;
i++;
}
printf("%d \n",j);
printf("Do it with another number? Y/N \n \n");
scanf("%s",&ch);
}
return 0;
Note that I have changed <= to < for your inner while, since you do not want to increment the value if the same n is inputted one after the other.
#include<stdio.h>
int main(){
int n;
char ch;
while(ch!='n')
{
printf("Enter the number upto which you want the sum of \n \n");
scanf("%d",&n);
int i=1;//it should be 1 in every loop of the number
int j=0;//the sum should also be initialized to zero to erase the previous value
while(i<=n)
{
j=j+i;
i++;
}
printf("%d \n",j);
printf("Do it with another number? Y/N \n \n");
scanf("%c",&ch);//this is a char not a string
}
return 0;
}
Due to the i is not initializing to 1 when the loop is coming for the second time there it is not going inside the loop and printing the previous value .
This question already has an answer here:
How to read / parse input in C? The FAQ
(1 answer)
Closed 5 years ago.
I am trying to get multiple words input and multiple lines into one array. But somewhere the code skips getting the input and skips to end the program. I have tried adding space before and after the ' %s' (or '%s ') but it won't work (maybe because it's inside a loop?). Would really appreciate anyone's help! It also starts to act weird if I enter more than two-three words :(
My goal is to find how many times a specific letter has occurred throughout all those words and lines.
#include <stdio.h> //include standard library
int main(){
int lineCount, occuranceCount;
printf("How many lines are you going to enter?");
scanf("%d", &lineCount);
char input[lineCount][100], searchChar;
for(int i=0; i<lineCount; i++){
printf("Please enter line #%d (100 characters of less):",i+1);
scanf("%s", &input[i]);
}
printf("What letter do you want to check the frequence in those lines? ");
scanf("%c", &searchChar);
for(int j=0; j<lineCount; j++){
for(int k=0; k<100; k++){
if(input[j][k] != '\0'){
if(input[j][k]==searchChar)
occuranceCount++;
}
}
}
printf("The letter occurs for %d time", occuranceCount);
return 0;
}
scanf(" %c", &searchChar);
^
You need the space over here to consume any \n from stdin.
Also scanf() will read one word not a line(space separated words) as you are thinking.
And also it is better to use strlen(input[j]) to know how much you should read.
Another thing, use size_t instead of int in the looping.
Intialize occuranceCount to 0.
Also to avoid buffer overrun exploits use scanf("%99s", input[i]); in your code.
In order to read a line you can use fgets().
1) Change
scanf("%c", &searchChar); --> scanf(" %c", &searchChar);
to get rid of any \n left in the input buffer from previous scanf
2) Change
for(int k=0; k<100; k++){ --> for(int k=0; k<strlen(input[j]); k++){
to avoid reading beyond the actual user input.
Besides that:
Never do scanf("%s", &input[i]); as the user can overflow your input buffer. At least change it to: scanf("%99s", &input[i]); but consider using fgets instead
Using fgets your program could be:
#include <stdio.h>
int main(){
size_t lineCount = 0, occuranceCount = 0;
printf("How many lines are you going to enter?");
scanf("%zu ", &lineCount);
if (lineCount == 0) return 0; // Input error
char input[lineCount][100], searchChar;
for(size_t i=0; i<lineCount; i++){
printf("Please enter line #%zu (100 characters of less):",i+1);
fgets(input[i], 100, stdin);
}
printf("What letter do you want to check the frequence in those lines? ");
scanf("%c", &searchChar);
for(size_t j=0; j<lineCount; j++){
for(size_t k=0; k<strlen(input[j]); k++){
if(input[j][k]==searchChar) occuranceCount++;
}
}
printf("The letter occurs for %zu time", occuranceCount);
return 0;
}
scanf using the %s always read until a ' '(whitespace) or '\n'(new line) is encountered, so you always can read only one word with scanf("%s", s1)...
if you want to read the spaces or new line characters you must use gets, or fgets(more secure than gets)
I have two problems with the code, the first one being that the program wants me to enter my number twice and the second one being that the program closes down immediately after it has finished its process.
I have tried to use the getchar() statement to stop it doing so but it doesn't seem to work.
#include <stdio.h>
int square(int); /*function prototype*/
main()
{
int x; /*defining the function*/
printf("Enter your number\n");
scanf_s("%d \n", &x); /*reading the users input*/
printf("Your new answer is %d \n", square(x)); /*calling the function*/
getchar();
getchar();
}
int square(y) /*actual function*/
{
return y * y;
}
Fix the issue by changing
scanf_s("%d \n", &x);
to
scanf_s("%d", &x);
The problem was that a whitespace character (space, newline etc) in the format string of scanf insructs scanf to scan and discard any number of whitespace characters, if any, until the first non-whitespace character.
As for the problem with getchar(), replace the first getchar() with:
int c;
while((c = getchar()) != '\n' && c != EOF);
This will scan and discard everything until a \n or EOF.
Also, change
main()
to
int main(void)
and
int square(y)
to
int square(int y)
I would recommend using scanf("%d", &x); to read your number. Your problem is that your argument looks like this:"%d \n" so the program expects you to enter your number AND \n. This way, you say how you want your x to look, and in your case, it expects it to be a numeric value, a space and end of line.
As for the closing one, use getch();. For this function, you need to include the conio.h like you did with stdio, meaningly: #include <conio.h>.
I have a problem writing code which does the following: declare a struct{char c; int x; } array and load it with scanf via a loop. After it's loaded, a call to function f will be made which will replace every occurrence of digits in the struct's component c with 0, and will return the sum of the digits replaced by zero.
Code and output are below and I have problem that the loop in the function f seems to iterate one time, and it gives out some really weird values.
This is an exam question so I have to use printf, scanf etc. Also I have that exam in an hour so any quick help is appreciated :)
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 2
struct par {
char c;
int x;
};
int f(struct par *niz) {
int i;
int n=0;
for(i=0; i<MAX; i++) {
if(isdigit(niz[i].c)) {
niz[i].c = niz[i].c-'0';
printf("niz[i].c = %d\n i = %d", niz[i].c, i);
n=n+niz[i].c;
niz[i].c='0';
}
}
return n;
}
void main() {
int n;
int i;
struct par niz[MAX];
printf("enter\n");
for(i=0; i<MAX; i++) {
scanf("%c", &niz[i].c);
scanf("%d", &niz[i].x);
}
n=f(niz);
for(int i=0; i<MAX; i++) {
printf("%d\n", niz[i].c);
printf("%d\n", niz[i].x);
}
printf("n = %d\n", n);
}
OUTPUT:
enter
2
2
2
niz[i].c = 2
i = 048
2
10
2
n = 2
When you press enter after the first input, the newline is not scanned by scanf and is left in the input buffer. When you then try to read the number scanf sees the newline and not a number so doesn't scan anything.
The simple solution to that is to add a leading space in front of the formats:
scanf(" %c", &niz[i].c);
scanf(" %d", &niz[i].x);
/* ^ */
This tells scanf to skip whitespace.
Use
niz[i].c = getchar();
instead of
scanf("%c", &niz[i].c);
or, you can use other better methods for getting char input discussed at SO,
Now,
You see second time you provided input only once, that is because the Enter you pressed after giving 2 as input to first char remained in input buffer, and was read on second iteration.
You are getting 10 as output, because, it is ASCII for \r, the Enter. It is not a digit, so not replaced to be '0'.
I am looking at your code (i am not using console for a decade, but ) here are some insights:
try to rename MAX with something else
do not know your IDE but sometimes MAX is reserved
and using it as macro can cause problems on some compilers
change scanf("%c", &niz[i].c) to scanf("%c", &(niz[i].c))
just to be shore that correct adsress is send to scanf
change scanf("%d", &niz[i].x) to scanf("%i", &(niz[i].x))
change "%d" to the correct value (this is main your problem)
"%c" for char
"%i" for int
Try to trace line by line and watch for improper variables change if above points does not help
weird values?
because you forgot "\n" after the line, so next print is behind the line "i = %d".
And, check return value of every function except ones that return void.
I'm doing an exercise in C but I have a problem when at the and I want to repeat the cicle (do while), infact if I type 1 the programme starts again by the top, but it doesn't stop at the gets(testo); . I tried plenty of ways to solve the bug without a solution, can anyone help me?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
main(){
int cch, cw, i, j, w, ord, f; //counter and index
char testo[80];
char alfa[50][25];
char swap[25];
do{
cch=0;
cw=0;
j=0;
w=0;
f=0;
for(i=0;i<80;i++){
testo[i]='\0';
}
printf("Write the text:\n");
gets(testo);
//initialization 2d array
for(i=0;i<50;i++){
for(j=0;j<25;j++){
alfa[i][j]='\0';
}
}
j=0;
//Count word and characters
if(testo[0]!='\0'){
cw=1;
for(i=0;testo[i]!='\0';i++){
cch++;
if(testo[i]==' '){
cw++;
j++;
}
}
}
if(cch==j){
printf("You haven't written any word\n\n");
}
else{
//Don't count double space
for(i=0;i<cch;i++){
if(testo[i]==' ' && testo[i+1]==' '){
cw--;
}
}
//Don't count as word if the text start with a space
if(testo[0]==' '){
cw--;
w--;
}
printf("\nThe text is composed by %d characters\n", cch);
printf("The text is composed by %d words\n", cw);
if(cw>0){
printf("\nUsed words:\n");
for(j=0;j<cch;j++){
if(testo[j]==' ' && testo[j+1]==' '){
//nothing to do
}
else{
if(testo[j]!=' '){
alfa[w][f]=testo[j];
f++;
}
else if(testo[j]=='\0'){
alfa[w][f]='\0';
f=0;
w=0;
}
else{
alfa[w][f]='\0';
w++;
f=0;
}
}
}
for(i=0;i<cw;i++){
printf("%d> %s\n", i+1, &alfa[i]);
}
//order
f=1;
printf("\nWords used in alphabetical order:\n");
while(f==1){
f=0;
for(i=0;i<cw-1;i++){
ord=strcmp(alfa[i],alfa[i+1]);
if(ord>0){
strcpy(swap,alfa[i]);
strcpy(alfa[i],alfa[i+1]);
strcpy(alfa[i+1],swap);
f=1;
}
}
}
for(i=0;i<cw;i++){
printf("%d> %s\n", i+1, alfa[i]);
}
}
}
printf("\nDo you want write another text? (1=yes) -> ");
scanf("%d", &j);
}while(j==1);
}
I know that isn't very optimized as code at the moment and has other errors, but I'm having problem on this.
Thank you.
PS: The code is tested on OpenVMS
It's because the scanf call at the end of the loop doesn't read the newline. Instead this newline is read by your gets call.
A simple solution is to add a space to the end of the scanf format string, like so:
scanf("%d ", &j);
This will make scanf skip trailing whitespace in the input.
Another solution is to put an extra fgets after the scanf, but then don't add the extra space in the format string:
scanf("%d", &j);
fgets(testo, sizeof(testo), stdin);
Or use fgets to get the line, and then use sscanf to extract the answer:
fgets(testo, sizeof(testo), stdin);
sscanf(testo, "%d", &j);
Your first and most obvious problem is with the left over newline. When you use scanf() here:
printf("\nDo you want write another text? (1=yes) -> ");
scanf("%d", &j);
}
and you use the %d format specificer, the function is looking for a number, when you enter a number really you're entering a number and a newline character
> 1<enter key> // which means on stdin you're getting '1''\n'
scanf() only picks up the 1 and leaves the newline which your gets() function then picks up, so it looks like it's skipping the input. All you need to do is consume that newline character, one quick fix would be to consume it with getchar():
printf("\nDo you want write another text? (1=yes) -> ");
scanf("%d", &j);
getchar();
}
Now your program works as you'd expect.
Other issues of note:
Your main should really be returning an int type, even if it's just a return 0
You shouldn't be using gets(), even then man page for gets() says Never use gets(). That's usually a good indication not to. ;) So replace that line with fgets(testo, sizeof(testo), stdin);
You missed a performance specificer here: printf("\nThe text is composed by % characters\n", cch); so you're getting garbage output, that should have been %d
Or you can try using the function flushall() just before gets()