I started my computer science course in college, and we're studying arrays. We have to write a program that reads a sequence of data, and prints it in reverse order. The char '%' declares the end of the sequence.
This is the program that I wrote:
#include <stdio.h>
int index;
int x;
int sequence[10];
int main () {
index = 0;
printf("Insert x: ");
scanf("%d", &x);
while (x != '%') {
sequence[index] = x;
printf("Insert x: ");
scanf("%d", &x);
index = index + 1;
}
while (index > 0) {
index = index - 1;
printf("%d", sequence[index]);
}
}
It reads the sequence via printf, saves each number in an array and when it receives a '%', it starts printing the sequence in reverse order, with the second while iteration.
The main problem is: when I try to run it, I get an error after that I enter '%', it starts printing back "Insert x: " lots of time, and then it crashes.
The second problem is: do I need to declare the size of the array?
Thank you.
This will scan an int. If it is successful the int will be added to the array until 10 ints have been added. If it fails to read an int, getchar will read a char and if the char is % the main loop will exit. If the char is not % it will try to read another int.
The size of the array needs to be declared.
#include<stdio.h>
#include<stdlib.h>
int main() {
int x = 0;
int index = 0;
int sequence[10] = {0};
int ch = 0;
printf ( "Input 10 integers (% to exit)\n");
while ( ch != '%') { // loop until ch is a %
if ( scanf ( "%d", &x) == 1) { // scanf read an int
sequence[index] = x;
index++;
if ( index >= 10) {
break; // too many inputs for array
}
}
else {
ch = getchar(); //scanf failed to read int. read a char and retry
}
}
while (index > 0) {
index = index - 1;
printf("%d\n", sequence[index]);
}
return 0;
}
As per your program. You are checking a character with integer value in while loop. Either you change your code like below or change condition in while loop as X!=? where ? is a ascii value of '%'. you can increase the array size but array value must be declared
#include <stdio.h>
int index;
char x;
char sequence[10]; //you can increase the array size here
int main () {
index = 0;
printf("Insert x: ");
scanf("%c", &x);
while (x != '%' && index <= 10) {
sequence[index] = x;
printf("Insert x: ");
scanf("%c", &x);
index = index + 1;
}
while (index > 0) {
index = index - 1;
printf("%c", sequence[index]);
}
return 0;
}
It crashes because inside the loop there are no condition to stop when you reach array max size.
At certain time : index = 10 -> sequence[10] doesn't exist because in c index must go from 0 to (array size - 1).
modify this
while (x != '%') {
to this
while ((x != '%') && (index <= 10)) {
For your question about array size declaration, the answer is YES, the size of an array must be always declared.
The reason is that scanf(3) returns the number of items read with that format string "%d", and as you don't check that number, it's getting one until you introduce the % (which is not a valid number), scanf(3) returns 0 (because it cannot convert that thing to an integer) and doesn't advance the file pointer from this point on, reading the % again and again. Each time, the last read value is getting assigned to one more cell of the array, overflowing it past of its limit (the last element is 9 but you allow to go up to element 10, one more), beggining to write other memory and probably crashing the program.
change the while loop to read so:
while ((scanf("%d", &x) == 1) && (index < 10)) { ...
Also, use < as the array is an array of 10 elements, numbered from 0 to 9.
Related
I'm trying to make a program in C where it prints from 0 to 100 then asks the user to print it again. It's not working.
#include <stdio.h>
#include <string.h>
int main()
{
int num;
char resposta[0];
resposta[0] = 's';
num = 0;
do
{
for (int i = 0; i < 100; i++)
{
num += 1;
printf("%i\n", num);
printf("Repetir?s/n\n");
scanf("%c", resposta[0]);
}
} while ((strcmp(resposta[0], "S") == 0) || (strcmp(resposta[0], "s") == 0));
return 0;
}
when declaring an array in C, the number in the brackets [] is not the index number, it is the total number of elements contained within the array. Setting char resposta[0]; means that resposta contains no elements.
This is different from when accessing elements, which uses a zero-index. So running scanf("%c", resposta[0]); is trying to access the first element, but there are zero elements within resposta, so that's likely why this isn't working.
I also figure I should add that it is entirely possible to just create a char variable that is not an array, since it seems you only need the one character. Just do char resposta; without the brackets.
Some more info on Arrays if you're interested: W3Schools
There are many issues.
You have an array that can contains 0 elements which is rather pointless, you want char resposta[1].
But you don't want an array of chars anyway. You're using the %c specifier you need a single char instead of an array of chars.
You're mixing up strings and chars. Change strcmp(resposta[0], "S")==0 to resposta == 'S', provided you have declared char resposta;.
You're asking the user if he wants to start over again in the for loop which is probably not what you want.
Basically you want this (untested code):
int main() {
char resposta;
resposta = 's';
int num = 0;
do {
num = 0;
for (int i = 0; i < 100; i++) {
num += 1;
printf("%i\n", num);
}
printf("Repetir?s/n\n");
scanf("%c", &resposta); // not the useage of the & operator here
} while (resposta == 'S' || resposta == 's');
}
One of the reasons it is not working is that the program stops to ask the user to continue inside the loop. Another failure is that the counter being used is not reset to zero for the second and subsequent runs. Another failure is the scanf format specifier that does not clear the newline out of the input buffer. The next 'get input' will not find an S/s to continue, but will pickup a LF and terminate the loop.
Things can be simplified if they are separated. The interaction with the user is very clearly defined and should be factored-out into its own function:
#include <stdio.h>
int again(void) {
puts( "Repetir? " );
char ch;
return scanf( " %c", &ch ) == 1 && (ch == 'S' || ch == 's' );
}
// Edit: Just noticed the OP title says "0 to 100"
void out(void) {
int i = 0;
while( i <= 100 ) printf( "%i\n", i++ );
}
int main() {
do out(); while( again() );
return 0;
}
I'm writing a code that must identify the letter 't' or 'T' in a word, before or after the middle of it.
If the first half of the word does contain a 't' or a 'T', the program should output a 1. If the first half does not contain the letter 't' or 'T', but the second half does, then the program should output a 2. Otherwise, if there is no 't' or 'T' in the word at all, the program's output should be -1. The word entered will not have more than 50 letters.
#include <stdio.h>
#include <string.h>
int main() {
char word[50];
int i = 0, length, t = 0, T = 0;
scanf("%s", word);
length = strlen(word);
t = word[i] == 't';
T = word[i] == 'T';
while(!t || !T) {
if((t || T) && i <= length / 2) {
printf("%d", '1');
} else if((t || T) && i > length / 2) {
printf("%d", '2');
//}else{
// printf("%d", '-1');
}
i++;
}
return 0;
}
If I enter any word and press enter, nothing is printed. Another thing is that when I remove the comment slashes from the two lines at the bottom, the program goes through an infinite loop.
Could someone please help?
This sounds like a school assignment, so I'll focus on advising/critiquing your code rather than giving a solution.
The first recommendation I have is to use a for loop instead of a while loop. A Rule of thumb in C is to only use a while loop when you actually don't have any idea how many things you need your program to look at.
You already have the length of the string, so set up your for loop to loop exactly once for each character.
Next you need to change how you are using printf. The %d format specifier is for printing integers, but you are passing it '1'. This is not an integer, it is the ascii representation of the symbol 1 (which is actually has the value 49, see the ascii table for more info)
You can either pass printf the value 1, or use the %c specifier, which expects ascii characters.
Better yet, just say printf("1");
That doesn't get you all the way there, but I think it lays the ground work so you can find the solution!
Condition !t || !T has no sense to be used as loop condition ...ask yourself how the loop will end ? you need just to check i is less than length
Second, the assignments t = word[i] == 't'; T = word[i] == 'T'; outside the loop have no sense ...you will be just pointing to the zero index of the string ...you should check all characters
third , the printf lines need to use %d
fourth , you appear not getting the purpose of the program printing inside loop will lead to printing many numbers and you just want to know if there is t or T you need to print single line.you may use variable int result=0; to hold the value you want and print it in the end ...of course you will need using break statement in the if((t || T) && i <= length / 2) and if((t || T) && i > length / 2) because no need for more searching
fifth, you should re-read , re-think , re-code the assignment before going bored and asking about it
sixth, there is a working version by modifying your code but you should try writing a good solution before looking at a solution as it better to solve your problems by yourself
#include <stdio.h>
#include <string.h>
int main() {
char word[50];
int i = 0, length, t = 0, T = 0;
scanf("%s", word);
length = strlen(word);
int result=0;
while( i<length) {
t = word[i] == 't';
T = word[i] == 'T';
if((t || T) && i <= length / 2) {
result=1;
break;
} else if((t || T) && i > length / 2) {
result=2;
break;
}else{
result=-1;
}
i++;
}
printf("%d",result);
return 0;
}
# include <stdio.h>
int main()
{
char name[20];
int age;
int siblings;
int childrens;
printf ("Hello my name is A.I, what is your name? \n");
scanf("%s", &name);
printf("how old are you : \n");
scanf("%d",&age);
printf("how many siblings you have: \n");
scanf("%d", &siblings);
printf("how many children you have: \n");
scanf("%d", &childrens);
printf("so your name is : %s \n", name);
printf("and your age is : %d \n", age);
printf("you have siblings : %d\n", siblings);
printf("so you have childrens : %d\n", childrens);
return 0;
}
I have a number, 321197186 which the user inputs. How can I store this number into an array one element at a time. Basically, I am trying to store the 1st digit into 0th element and so on. And then I have to do some computation on that number.
Represent your number as a string, where every character of that string will be the corresponding digit of your number.
There are a plethora of method to read a string, but I suggest you use fgets() like this:
#include <stdio.h>
#include <string.h>
#define MAX_LEN 10
int main (int argc, char *argv[])
{
char number[MAX_LEN];
printf("Enter a number: \n");
fgets(number, MAX_LEN , stdin);
printf("%s\n", number);
return 0;
}
With a for loop, you access the characters (digits) of the string (number) one by one, if you like.
I suggest you also eat the trailing newline that fgets() leaves in the input array, as already explained in Removing trailing newline character from fgets() input.
Alternative solution proposed by bruno#:
scanf("%9s", number);
Read more in C - scanf() vs gets() vs fgets().
Assume you have
int num;
if (scanf("%d", &num) != 1)
{
// Input error
exit(1);
}
// Now the user input is available in num
then you do
#define MAX_DIGITS 32
int digits[MAX_DIGITS] = { 0 };
int index = 0;
while(num != 0 && index < MAX_DIGITS)
{
digits[index] = num % 10;
++index;
num = num / 10;
}
// Now the array digits holds the individual digits
// and index holds the number of valid digits
You can consider this logic in C -
number = 321197186
while(number> 0) - leave if number becomes 0
{
int last_digit = number % 10; - Last digit from the number
printf("%d",last_digit);
number = number / 10; - to get the remaining number.
}
This can be also done in Python as -
number = 321197186
list1 = []
for i in str(number):
list1.append(i)
print(list1)
store this number into an array one element at a time.
Let us take advantage of the input process to have a convenient way to determine the length of input including leading zeros (but not input with a sign, leading spaces) by using "%n" to record the offset of the scan.
Use % 10 to exact the least significant decimal digit of the number.
int number;
int offset;
if (scanf("%d%n", &number, &offset) == 1) {
int a[offset]; // VLA
while (offset > 0) {
a[--offset] = number % 10;
number /= 10;
}
for (int i = 0; i < sizeof a/sizeof a[0]; i++) {
printf("a[%d] = %d\n", i, a[i]);
}
}
Output
a[0] = 3
a[1] = 2
a[2] = 1
a[3] = 1
a[4] = 9
a[5] = 7
a[6] = 1
a[7] = 8
a[8] = 6
But as bruno points out, you just have to check it as a string as an user input with fgets is an array of characters (even if we are talking about numbers).
For more detail:
for(i=0;i<sizeof(array_input);i++){
//Store the char into another array
}
I'm trying to find the frequency of digit into given string,which contain digit and letters. When i run the same program i get different result, look like random output. where is the problem ?
int main() {
char num[1001];
int digit[10];
int j,i;
int count;
scanf("%s",num);
for(i=48;i<=57;i++)
{
count = 0;
for(j=0; num[j] != EOF;j++)
{
if(num[j] == i)
{
count++;
}
}
printf("%d ",count);
}
return 0;
}
You have missed an & in the line with scanf before num. Correct code should be:
scanf("%s", &num);
When you are scanning for the value, you need to provide the address of the variable. That is you let your program know where to put the value. &num points to the address of the variable num. But if you just write scanf("%s",num) you are providing value of the num variable, which you don't care at all. You'll be overwriting that value anyway.
At the end of the string, computer puts a null character \0 whose ASCII value is 0, to denote that this is the end of the string. Kind of like a '.' but for a computer. So you check until you find the null character in the for loop like: num[j] != '\0' [Not EOF]
I don't see any issue here, it seems output is not readable properly
so try printing correctly like
printf("%c=>%d ",i, count);
so that you can read what number how many times. if you find wrong frequency,
post the input for which you are getting wrong output.
It seems like you're trying to compare a char element with an integer type.
for example:
char num[7] = {"ABC123");
if (num[3] == 1)
{
printf("True\n");
}
else
{
printf("False\n");
}
return 0;
// This will return False, even though the element at index 3 is "1".
I've ran your code, and it seems like the output is the same given the same input.
Edit:
We wanted to compare a two digit number to a char data type - which is essentially a character - a one digit number/case.
When we take a number N and modulo by 10, we get the last digit, example:
48 % 10 = 8
To get the first digit we simply divide by 10, and take the quotient, example:
48 / 10 = 4 (remainder 8).
With this knowledge, we can compare the n-th char with first digit, and the n+1-th char with the last one (given that we only compare two digits, we'll stop at n+1-th).
Tip: a number char can be turned into a int using char = char - '0'
char num[1001];
int digit[10];
int j,i;
int count;
scanf("%s",num);
for(i=48;i<=57;i++)
{
count = 0;
for(j=0; num[j] != EOF;j++)
{
if(num[j] - '0' == i / 10 && num[j+1] - '0' == i % 10)
{
printf("%c", num[j] - '0');
count++;
}
}
printf("%d: %d \n",i, count);
}
printf("\n");
return 0;
// This code will print the digits and the frequency in a new line:
48: n times
49: n times
.
.
.
57: n times
The Program:
This was supposed to be a simple reverse polish notation addition program, please ignore the EOF break thing, it's a placeholder.
Input is c, always one numeral number, it gets transfered to x where every next numeral c will be added to the number x, so for example when we input c as 1,2 and 3 x will be 123.
When we input 'e' it will mark the start of a new number, and x will be transfered to the stack[0] after the entire stack gets pushed back, and x will become 0. When inputing '+' addition happens, the last two numbers will be summed, x and the first number in the stack, or the first and second number in the stack, or the first number in the stack will duplicate itself.
The Problem:
The first number in the stack array will randomly become 0 and I cannot see where I made the error. The first number (stack[0]) only gets the value zero at the start, never again. At times when inputting '+' it will just get a value.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int stack[16];
int x;
int i;
char c;
//int c;
x=0;
for (i = 0; i < 16; i++)
{
stack[i]=0;
}
while(1)
{
//input character
scanf("%s", &c);
if (c == EOF) break;
//put x to stack
else if (c == 'e')
{for (i = 15; i >0; i--)
{
stack[i]=stack[i-1];
}
stack[0] = x;
x = 0;
}
//reverse polish addition
else if (c == '+')
//if x is 0 go immediately to the stack
{if (x == 0)
//if both x and the second number in array are 0 just duplicate the first number
if (stack[1] == 0)
stack[0] = stack[0] + stack[0];
//if only x is 0 add the first number on the second
else
{
stack[0]=stack[0]+stack[1];
//push back the array to fill the gap on the second number
for (i = 1; i <15; i++)
{
stack[i]=stack[i+1];
}
}
else
{
stack[0] = stack[0] + x;
x = 0;
}
}
else
{
x = x * 10 + ((int)c-0x30);
// putchar(c);
}
printf("X=%d\n",x);
//print stack
for (i = 0; i < 16; i++)
{
printf("%d \t",stack[i]);
}
printf("\n");
}
return 0;
}
Problem 1
scanf("%s", &c); causes undefined behavior. Use scanf(" %c", &c);.
Problem 2
c is never going to be equal to EOF by using scanf. Hence, the following line is useless.
if (c == EOF) break;
The following will take care of both problems.
// Use " %c" instead of "%c" to skip leading whitespace characters.
while ( scanf(" %c", &c) == 1 )
{
}