Input to array of strings won't show? - c

I'm in C and I'm supposed to have an input of numbers (don't know how many) formatted into one column without storing them into an array of integers. I can't figure out why my code won't read the input and out put it. Please help.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i;
char *nums[400];
for (i=0; i<nums; i++) {
scanf(nums[i]);
printf( "%.*s", 3, nums[i] );
}
return 0;
}

You have an array of 400 pointers, but you've never initialized them. Instead, you could declare a 2-dimension array:
char nums[400][4];
Then you're trying to use nums as a limit to the for loop. What you actually want is the number of elements in nums, which is sizeof(nums)/sizeof(nums[0]); or you could define a macro that specifies the size of the array.
Next, you left out the format string argument to scanf().
#include <stdio.h>
#include <stdlib.h>
#declare SIZE 400
int main()
{
int i;
char *nums[SIZE][4];
for(i=0; i<SIZE; i++){
scanf("%3s", nums[i]);
printf( "%.*s", 3, nums[i] );
}
return 0;
}

As Baramar correctly and thoroughly explained your main problems, I think I might have a different understanding of your problem. You want a given string of number, e.g.: 2134567896543245678 and print it out in a single column, neatly formated in rows of three digits each like that:
213
456
789
654
324
567
8
without an intermittent array of integers.
That could be done like e.g.: this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 512
int main()
{
int res;
// for the scanf input, set all to '\0'
char buffer[BUFFER_SIZE + 1] = { '\0' }, *idx;
size_t len, i;
// restrict max-size to BUFFER_SIZE
res = scanf("%512s", buffer);
if (res != 1) {
exit(EXIT_FAILURE);
} else {
if (strcmp(buffer, "exit") == 0) {
exit(EXIT_SUCCESS);
}
// TODO: check if the buffer contains all digits
len = strlen(buffer);
idx = buffer;
for (i = len; i >= 3; i -= 3, idx += 3) {
printf("%.3s\n", idx);
}
// last entries, if any
if (*idx != '\0') {
printf("%s\n", idx);
}
}
exit(EXIT_SUCCESS);
}
If you get actual integers in a row like e.g.: 12 3123 23478 34 5456 567456 567 678 you can use something like that:
EDIT
After the comment by the OP to use floating points I changed the code to accept input of the form:
24722.319352 51433.662233
56087.991042 49357.684934 67875.375848 68421.563197
54521.615295
22744.470483
38097.001461 80878.250982
92131.575748 7217.137271
20750.671365 7620.695008 37118.391541 28655.609469 46885.110202 87114.202312
46462.577299
20557.716648
And the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXNUM 400
int main()
{
int res;
int i = 0, m;
// input and two temporary variables
double in, in1, in2;
for (m = 0; m < MAXNUM; m++) {
res = scanf("%lf", &in);
if (res != 1) {
break;
} else {
switch (i) {
case 0:
// set value of first temporary variable to input
in1 = in;
// increment indicator indicating position in output row
i++;
break;
case 1:
in2 = in;
i++;
break;
case 2:
// print the three numbers and a newline
fprintf(stdout, "%f %f %f\n", in1, in2, in);
// reset counter
i = 0;
break;
}
}
}
// if there are still numbers, print them
if (i != 0) {
if (i == 1) {
fprintf(stdout, "%f\n", in1);
} else {
fprintf(stdout, "%f %f\n", in1, in2);
}
}
exit(EXIT_SUCCESS);
}
Try it out with
$ gcc-4.9 -O3 -g3 -W -Wall -Wextra -std=c11 sc.c -o sc
$ ./sc < floatin
24722.319352 51433.662233 56087.991042
49357.684934 67875.375848 68421.563197
54521.615295 22744.470483 38097.001461
80878.250982 92131.575748 7217.137271
20750.671365 7620.695008 37118.391541
28655.609469 46885.110202 87114.202312
46462.577299 20557.716648
If you enter less than 400 entries you need to end with EOF which can be triggered in most Unix shells with ctrl+d or set an entry to end the entries like e.g.: -1 if all you have is positive numbers and check for it to break out of the loop. If you submit a file like in the example above it works automatically.

Related

I have problem with reading input with blank spaces

I made this function to get input:
void entrada_dados(Time* time, int i){
scanf("%s %d %d", time[i].nome, &time[i].gols_marcados, &time[i].gols_sofridos);
};
The input is in this form:
2
Campinense
23
12
ABC
30
13
The main is:
int main(void) {
int n = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++){
entrada_dados(time, i);
}
....
My problem is when the team name have some space like to "São Paulo". I have tried some forms to solve, but no one solved my problem.
I tried:
void entrada_dados(Time* time, int i){
fscanf(stdin, "%[^\n] %d %d", time[i].nome, &time[i].gols_marcados, &time[i].gols_sofridos);
};
and:
void entrada_dados(Time* time, int i){
fgets(time[i].nome, 100, stdin);
scanf("%d", &time[i].gols_marcados);
scanf("%d", &time[i].gols_sofridos);
}
but in the first case the output have nothing, and second case the output miss some cases. Someone can help me to understand this problem?
Edit 1:
The definition of .name is:
typedef struct Time{
char nome[100];
int gols_marcados;
int gols_sofridos;
} Time;
Edit 2:
Solution:
One way to solve it:
Try two fscanfs fscanf(stdin, " %[^\n]", time[i].nome);
fscanf(stdin, "%d %d", &time[i].gols_marcados, &time[i].gols_sofridos);
Thank you guys.
Because you have to handle strings with spaces, it's better to use fgets for those.
But mixing fgets and scanf doesn't work too well. We can replace scanf with fgets followed by sscanf.
To decode numbers, we can use strtol or sscanf
We take advantage of the fact that each element/member of Time appears on a separate line in the input file, so we can do fgets for every line. This simplifies the code and makes error checking easier.
Here is the refactored code. It is annotated.
I didn't do this, but, if these sequences are done a lot, we can combine some of these sequences in helper functions to reduce some code replication (e.g. a function that combines the fgets followed by the sscanf)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Time {
char nome[100];
int gols_marcados;
int gols_sofridos;
} Time;
// RETURNS: 1=valid, 0=syntax error
int
entrada_dados(Time *timelist, int i)
{
char buf[100];
char *cp;
Time *tim = &timelist[i];
int valid = 0;
do {
// get name
if (fgets(tim->nome,sizeof(tim->nome),stdin) == NULL)
break;
// strip newline
tim->nome[strcspn(tim->nome,"\n")] = 0;
// get number using strtol
if (fgets(buf,sizeof(buf),stdin) == NULL)
break;
tim->gols_marcados = strtol(buf,&cp,10);
if (*cp != '\n')
break;
// get number using sscanf
if (fgets(buf,sizeof(buf),stdin) == NULL)
break;
if (sscanf(buf,"%d",&tim->gols_sofridos) != 1)
break;
// all input is okay
valid = 1;
} while (0);
return valid;
};
int
main(void)
{
int n = 0;
#if 0
scanf("%d", &n);
#else
char buf[100];
if (fgets(buf,sizeof(buf),stdin) == NULL)
exit(1);
sscanf(buf,"%d",&n);
#endif
// allocate sufficient space
Time *timelist = malloc(sizeof(*timelist) * n);
// read in data
int valid = 0;
for (int i = 0; i < n; i++) {
valid = entrada_dados(timelist, i);
if (! valid)
break;
}
// show the data
if (valid) {
for (int i = 0; i < n; i++) {
Time *tim = &timelist[i];
printf("nome='%s' gols_marcados=%d gols_sofridos=%d\n",
tim->nome,tim->gols_marcados,tim->gols_sofridos);
}
}
return 0;
}
Here is the program input:
3
Campinense
23
12
ABC
30
13
São Paulo
17
82
Here is the program output:
nome='Campinense' gols_marcados=23 gols_sofridos=12
nome='ABC' gols_marcados=30 gols_sofridos=13
nome='São Paulo' gols_marcados=17 gols_sofridos=82

how can i sum realy big number? [duplicate]

This question already has answers here:
Digital Root in c
(2 answers)
Closed 11 months ago.
So you have to do:
11 = 1+1 = 2
3578 = 3+5+7+8 = 23 = 2+3 = 5
But the problem is that the number can be very large(consist of 10,000 digits)
But even with the easiest entrances it doesn't work:
Input : 11
Output: 2798 (and it always changes, but remains a 4-digit number)
Can someone explain why is this happening?
And how can I summarize each digit of a very large number?
You got that huge number becuase your program is adding the ASCII value of various characters.
Some improvements:
Don't use "%s", use "%<WIDTH>s", to avoid buffer-overflow
Use size_t to iterate through an array, instead of unsigned long long int
Instead of using bare return 0;, use return EXIT_SUCCESS;, which is defined in the header file stdlib.h.
always check whether scanf() input was successful or not
Don't check for '\n', because string from scanf() ends at both SPACES and NEWLINE.
adding +1 to array size for NULL terminating character
Use "%zu" instead of "%lld" for size_t
Final Code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void) {
char buffer[10001] = {0};
if(scanf("%10000s", buffer) != 1)
{
perror("bad input");
return EXIT_FAILURE;
}
size_t result = 0;
for(size_t i = 0; buffer[i]; i++) {
if(isdigit(buffer[i])){
result += buffer[i] - '0';
}
else {
perror("only digits are valid");
return EXIT_FAILURE;
}
}
printf("%zu\n", result);
return EXIT_SUCCESS;
}
Output:
1112
5
TRY IT ONLINE
You can do it without occupying memory
#include <ctype.h>
#include <stdio.h>
int main(void) {
int sum = 0;
for (;;) {
int ch = getchar();
if (!isdigit((unsigned char)ch)) break; // leave loop with ENTER, EOF, 'a', ...
sum += ch - '0';
}
printf("sum of digits is %d.\n", sum);
return 0;
}
Edit: see code running at ideone
Wiki Digital Root provides a shortcut for getting the final single digit.
Validate your input string has only numeric digits
Find the sum of all digits in ASCII form
Make use of congruence formula to get the result.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX_NUM_LEN 10000
int digitRoot (int n) {
if (0 == n) return 0;
return (0 == (n % 9)) ? 9 : (n % 9);
}
int main () {
char str_num [MAX_NUM_LEN];
printf ("Finding Digital Root\nEnter a number : ");
if (NULL == fgets (str_num, sizeof (str_num), stdin)) {
perror ("Reading input string");
return 2;
}
int slen = strlen (str_num);
// remove new line if found
if ('\n' == str_num[slen - 1]) str_num[--slen] = '\0';
// validate input
int digitSum = 0;
for (int ni = 0; ni < slen; ++ni) {
if (!isdigit ((unsigned char) str_num[ni])) {
printf ("\nERROR: Invalid digit [%c]\n", str_num[ni]);
return 1;
}
digitSum += str_num[ni] - '0';
}
printf ("\nDigital Root is [%d]\n", digitRoot (digitSum));
return 0;
}

Code Blocks error when using while(scanf) in C

I have attached a piece of code below which works perfectly fine in an online compiler but fails to work in Code Blocks compiler when using C. I have attached screenshots as well.
#include <stdio.h>
int main() {
int i = 0;
int array[100];
while(scanf("%d",&array[i])>0)
{
i++;
}
for(int j=0;j<i;j++)
{
printf("%d ",array[j]);
}
return 0;
}
Using Online compiler(GeeksForGeeks)
Using CODEBLOCKS compiler
There is no error, your while loop will go on until an invalid input is entered, you have no limit for the number of inputs so it will continue taking values, which may later become a problem since your container only has space for 100 ints.
It stops on some online compilers because of the way they use stdin inputs, it's basically a one time readout.
Examples:
It stops here, has one time stdin readout.
It doesn't stop here, has a console like input/output.
So if you want to stop at a given number of inputs you can do something like:
//...
while (i < 5 && scanf(" %d", &array[i]) > 0)
{
i++;
}
//...
This will read 5 ints, exit the loop and continue to the next statement.
If you don't really know the number of inputs, you can do something like:
//...
while (i < 100 && scanf("%d", &array[i]) > 0) { // still need to limit the input to the
// size of the container, in this case 100
i++;
if (getchar() == '\n') { // if the character is a newline break te cycle
// note that there cannot be spaces after the last number
break;
}
}
//...
The previous version lacks some error checks so for a more comprehensive approach you can do somenthing like this:
#include <stdio.h>
#include <string.h> // strcspn
#include <stdlib.h> // strtol
#include <errno.h> // errno
#include <limits.h> // INT_MAX
int main() {
char buf[1200]; // to hold the max number of ints
int array[100];
char *ptr; // to iterate through the string
char *endptr; // for strtol, points to the next char after parsed value
long temp; //to hold temporarily the parsed value
int i = 0;
if (!fgets(buf, sizeof(buf), stdin)) { //check input errors
fprintf(stderr, "Input error");
}
ptr = buf; // assing pointer to the beginning of the char array
while (i < 100 && (temp = strtol(ptr, &endptr, 10)) && temp <= INT_MAX
&& errno != ERANGE && (*endptr == ' ' || *endptr == '\n')) {
array[i++] = temp; //if value passes checks add to array
ptr += strcspn(ptr, " ") + 1; // jump to next number
}
for (int j = 0; j < i; j++) { //print the array
printf("%d ", array[j]);
}
return EXIT_SUCCESS;
}

My program doesn't manipulate a string's values correctly

I need to code a program that gets input values for a string, then it ignores the characters that are not digits and it uses the digits from the string to create an integer and display it. here are some strings turned into integers as stated in the exercise.
I wanted to go through the string as through a vector, then test if the each position is a digit using isdigit(s[i]), then put these values in another vector which creates a number using the digits. At the end it's supposed to output the number. I can't for the life of it figure what's wrong, please help.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main()
{
char *s;
scanf("%s", s);
printf("%s\n", s);
int i, n=0, v[100], nr=0;
for(i=0; i<strlen(s); i++)
{
if (isdigit(s[i]) == 1)
{
v[i] = s[i];
n++;
}
}
for(i=0;i<n;i++)
{
printf("%c\n", v[i]);
}
for(i=0; i<n; i++)
{
nr = nr * 10;
nr = nr + v[i];
}
printf("%d", nr);
return 0;
}
The pointer s is unintialized which is your major problem. But there are other problems too.
isdigit() is documented to return a non-zero return code which is not necessarily 1.
The argument to isdigit() needs to be cast to unsigned char to avoid potential undefined behaviour.
Your array v is also using the same index variable i - which is not right. Use a different variable to index v when you store the digits.
You need to subtract '0' to get the each digits integer equivalent.
scanf()'s format %s can't handle inputs with space (among other problems). So, use fgets().
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char s[256];
fgets(s, sizeof s, stdin);
s[strcspn(s, "\n")] = 0; /* remove trailing newline if present */
printf("%s\n", s);
int i, n = 0, v[100], nr = 0;
size_t j = 0;
for(i = 0; i < s[i]; i++)
{
if (isdigit((unsigned char)s[i]))
{
v[j++] = s[i];
n++;
}
}
for(i = 0;i < j; i++)
{
printf("%c\n", v[i]);
}
if (j) { /* No digit was seen */
int multiply = 1;
for(i= j-1 ; i >= 0; i--) {
nr = nr + (v[i] - '0') * multiply;
multiply *= 10;
}
}
printf("%d", nr);
return 0;
}
In addition be aware of integer overflow of nr (and/or multiply) can't hold if your input contains too many digits.
Another potential source of issue is that if you input over 100 digits then it'll overflow the array v, leading to undefined behaviour.
Thanks a lot for your help, i followed someone's advice and replaced
v[i] = s[i] -> v[n] = s[i] and changed char *s with char s[100]
now it works perfectly, i got rid of the variable nr and just output the numbers without separating them through \n . Thanks for the debugger comment too, I didn't know I can use that effectively.
Firstly, you did not allocate any memory, I changed that to a fixed array.
Your use of scanf will stop at the first space (as in the first example input).
Next, you don't use the right array index when writing digits int v[]. However I have removed all that and simply used any digit that occurs.
You did not read the man page for isdigit. It does not return 1 for a digit. It returns a nonzero value so I removed the explicit test and left it as implicit for non-0 result.
I changed the string length and loop types to size_t, moving the multiple strlen calls ouside of the loop.
You have also not seen that digits' character values are not integer values, so I have subtracted '0' to make them so.
Lastly I changed the target type to unsigned since you will ignore any minus sign.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char s[100]; // allocate memory
unsigned nr = 0; // you never check a `-` sign
size_t i, len; // correct types
if(fgets(s, sizeof s, stdin) != NULL) { // scanf stops at `space` in you example
len = strlen(s); // outside of the loop
for(i=0; i<len; i++) {
if(isdigit(s[i])) { // do not test specifically == 1
nr = nr * 10;
nr = nr + s[i] - '0'; // character adjustment
}
}
printf("%u\n", nr); // unsigned
}
return 0;
}
Program session:
a2c3 8*5+=
2385
Just use this
#include <stdio.h>
#include <ctype.h>
int main()
{
int c;
while ((c = getchar()) != EOF) {
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '\n':
putchar(c); break;
}
}
return 0;
} /* main */
This is a sample execution:
$ pru_$$
aspj pjsd psajf pasdjfpaojfdapsjd 2 4 1
241
1089u 0u 309u1309u98u 093u82 40981u2 982u4 09832u4901u 409u 019u019u 0u3 0ue
10890309130998093824098129824098324901409019019030
Very elegant! :)

How to find the length of an input

i am trying to measure how many numbers my input has.
if i input the following line: 1 2 65 3 4 7,
i want the output to be 8.but what I'm getting is 1 2 3 4.
#include <stdio.h>
int main(void) {
int data;
int i = 1;
while (i <= sizeof(data)) {
scanf("%d", &data)
printf("%d", i);
i++;
}
}
You are printing i which have no relation to the input at all. So no matter what your input is, you'll get 1234
sizeof(data) is the same as sizeof(int), i.e. a constant with value 4 on your system.
If you want to count the number of numbers and don't care about the value of the individual number, you could do:
#include <stdio.h>
#include <ctype.h>
int main(void) {
char s[1024];
char* p;
int i = 0;
fgets(s, 1024, stdin);
p=s;
while (*p != '\0')
{
if (!isdigit(*p))
{
p++;
}
else
{
i++; // Found new number
// Search for a delimiter, i.e. skip all digits
p++;
while (*p != '\0' && isdigit(*p))
{
p++;
}
}
}
printf("We found %d numbers", i);
return 0;
}
Output:
We found 6 numbers
Notice that this code will accept any non-digit input as delimiter.
put the scanf before the while-loop and move the printf after the while-loop.
I'm also providing solution according to my openion.
#include <stdio.h>
int main(void) {
int data = 1;
int i = 0;
// here data != 0 is trigger point for end input,
// once you done with your inputs you need to last add 0 to terminate
while (data != 0) {
scanf("%d", &data)
printf("Collected Data: %d", data);
i++;
}
printf("Total number of inputs are %d.", i);
}
Hope this solution helps you.
Here is my solution:
#include <stdio.h>
#include <stdlib.h>
int main() {
int i = 0;
int data[100]; // creating an array
while(1) { // the loop will run forever
scanf("%d", &data[i]);
if (data[i] == -1) { //unless data[i] = -1
break; // exit while-loop
}
i++;
}
printf("%d\n", data[2]); // print 2nd integer in data[]
return 0;
}
Do not forget to hit enter once you entered an int. Output of the program:
2
56
894
34
6
12
-1
894
Hope that helps. :)

Resources