I'm trying to cope with my exercise. I have to input n (up to 10^6) integers separated by space in single line and sum them.
For e.g. 0 1 541 10 54 100000000...
I tried scanf, but it takes to much time (Limit for this algorithm is only 1sec):
int n;
long long int sum;
scanf("%d\n", &n);
while(n--){
scanf(" %d", &value);
suma+= value;
}
I decided to read that line as char array, and then split using space as delimiter.
int n;
long long int sum;
scanf("%d\n", &n);
char tab[n];
scanf("%[^\n]s", tab);
char* split=strtok(tab," ");
while(split != NULL){
suma += atoi(split);
split=strtok(NULL," ");
}
But it doesn't work :/ Probably there is a problem with bounds of array, but I'm not sure and I can't repair this error.
Fix last call to strtok() to receive argument ++split instad of NULL
Related
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;
}
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 answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
scanf() leaves the newline character in the buffer
(7 answers)
Closed 5 years ago.
This is my code
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
scanf("%d",&N);
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}
Given inputs are:
N = 3
red 50,
50 green,
blue 50
Here the problem is fgets inside for loop gets executed only twice if N is 3. This problem doesn't arise if I comment the scanf statement. Can somebody explain me what is causing this problem and how it can be solved?
After a few hours of scratching my head, I realized the following:
Avoid using scanf. Managing buffer overflows is not easy.
Always try to use fgets to get user inputs.
Try this code here:
#include<stdio.h>
#include<stdlib.h>
int main(){
int N,i,radius,diameter,count =0;
char str[20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = strtoul(buffer,NULL,10);
char color[N][20];
printf("%d\n",sizeof(color));
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
if(color[i][strlen(color[i])-1]=='\n'){
color[i][strlen(color[i])-1]='\0';
}
else{
while((getchar())!='\n');//this is just to prevent an overflow for the size of char arrays
}
}
for(i=0;i<N;i++){
printf("%s\n",color[i]);
}
return 0;
}
Notice that I first input a number inside a char array. Convert that into a number using strtoul(string to unsigned long). Now inside the for loop I again use fgets to take inputs. The problem was, if you enter a string greater than 19 chars, the remaining part will be left inside the input buffer and shall be assigned to the subsequent input. To manage that I used getchar inside a while loop, which consumes all the unnecessary characters and the newline character from the input stream. Avoid using fflush as it may result in undefined behavior as answered here
-fflush(stdin) function does not work
-http://www.geeksforgeeks.org/clearing-the-input-buffer-in-cc/
Also note that you are using Variable Length Arrays which may not always be a good choice. Older versions of c compiler prohibit them. You had declared color[N][20] first before initializing N. That was wrong.
I suggest you to read this too
-C - scanf() vs gets() vs fgets()
After using scanf you'd need to clean the buffer. I suggest to never use scanf, just use fgets and then convert the output to a number:
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = atoi(buffer); // you need to include stdlib.h
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}
Due to this reference:
https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
this will be correct:
int _tmain(int argc, _TCHAR* argv[])
{
int N, i, radius, diameter, count = 0;
char str[10];
char color[20];
printf("Get the num : ");
scanf_s("%d", &N);
printf("Enter the mesage\n");
//for (i = 0; i<N; i++){
fgets(color, 20, stdin);
//}
//for (i = 0; i<N; i++){
printf("%s", color);
//}
return 0;
}
I changed scanf to scanf_s for VC++.
I'm new to using fgets so I don't know what I'm doing wrong. I need to make a table of floats but I keep seg faulting during the standard input. I took out all the "unnecessary" code for readability so yes I do use all the arguments in the parameters. It seg faults even when I enter one number.
typedef struct row
{
int column;
float value[20];
}ROW;
//in main ROW table[100];
void makeTable2(ROW* table, int* row, int* column)
{
int counter = 0, counter2;
int y = 0;
char str[256], again;
printf("Enter in the table: ");
do{
fgets(str, 256, stdin);
while(sscanf(str, "%f", &table[*row].value[y]))
y++;
(*row)++;
printf("Add another row? (y or n)? ");
scanf("%c", &again);
}while(again == 'y' || again == 'Y');
}
in line
while(sscanf(str, "%f", &table[*row].value[y]))
you're reading your first number every time, NOT NEXT, only first, and get buffer overflow when y exceeds value 20.
Try scanf() every value separately.
while(sscanf(str, "%f", &table[*row].value[y]))
y++;
That's an infinite loop. You always read from the first float value present in the str buffer and eventually y become more than 19 and there is segmentation fault.
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.