C programming, error loop due to scanf? - c

I have question about scanf a string. I am completing a practice exercise on encoding a Vigenere cipher.
It is easy to solve it at other language but in C I have trouble and I don't know why it is.
This is my code.
#include<stdio.h>
#include<string.h>
main()
{
char mes[1000];
char key[100];
int n=strlen(mes);
int cipher[n],i,j=0;
printf("Enter message \n");
scanf("%s",mes);
printf("Enter keyword \n");
scanf("%s",key);
printf("len message= %d \n",strlen(mes));
for(i=0;i<strlen(mes);++i)
{
mes[i]=toupper(mes[i]);
key[j]=toupper(key[j]);
if(j==strlen(key))
j=0;
cipher[i]=((mes[i]-0x41)+(key[j]-0x41)) % 26;
printf("%c",cipher[i]+0x41);
++j;}
printf("\n");
}
My code work well if mes array input is less than 16 character, but if mes input larger the program loop infinite. I don't know why.
If I change type of cipher array to char type, it seem work better, but the result still have wrong output like this:
Enter message
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Enter keyword
eeeeeeeeeeeeeeeeeee
len of message= 45
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE�EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAEEEEEEE
So can you explain:
1) Why my code do wrong if cipher array is an int type?
2) If cipher is char, the output better but why It have wrong output?

Couple of problems:
Allocating memory for cipher doesn't work properly
int n=strlen(mes); // mes has nothing now..so n=0!
int cipher[n],i,j=0;
Rolling back j should be done after increment .
Put this piece after you read both inputs..it should work for any length<100
int cipher[strlen(mes)];
for(i=0;i<strlen(mes);++i)
{
mes[i]=toupper(mes[i]);
key[j]=toupper(key[j]);
cipher[i]=((mes[i]-'A')+(key[j]-'A')) % 26; //use 'A' for better readability
printf("%c",cipher[i]+'A');
++j;
if(j==strlen(key))
j=0;
}

In simple words, You wrote int n=strlen(mes); before giving any input,Now how would you determine the size of input when its still not given,See my comments in below code,
char mes[1000];
char key[100];
int n,i,j=0;
printf("Enter message \n");
scanf("%s",mes);
n=strlen(mes);//Determining Size of Input after giving it.....
int cipher[n];//Add This Here,Now You Create a array after Determining input size.
printf("Enter keyword \n");
scanf("%s",key);
printf("len message= %d \n",strlen(mes),strlen(key));

You didn't initiate the length of the chiper array correctly.. In your code:
char mes[1000];
char key[100];
int n=strlen(mes);
int cipher[n];
The length of chiper array here is undefined..
Unless you write something like:
int chiper[1000];
BR//Ari

Related

Getting an infinite running program when using scanf

I'm getting an infinite running programm when I use the following code to read a string from keyboard and save it within a structured vector.
scanf("%s", strk_zgr_fp->bezeichnung, (int)sizeof(strk_zgr_fp->bezeichnung - 1));
Simply nothing happens after this line is reached and the program runs infinitly.
I know scanf() isn't recommended. We're using it only within our C beginners course and I want you to keep it in mind, ie please don't recommend other function rather than above mentioned for the moment.
Any help is much appreciated, thanks in advance.
#include <stdio.h>
typedef struct {
int nummer;
char bezeichnung;
int menge;
float preis;
} artikel;
void eingabe_artikel(artikel *strk_zgr_fp, int i_fp);
void ausgabe_artikel(artikel *strk_zgr_fp, int i_fp);
void main(void) {
artikel artikelliste[10];
artikel *strk_zgr;
int anzahl;
do {
printf("Bitte eine #Artikel eingeben [<= 10]: ");
scanf("%d", &anzahl);
if(anzahl < 1 || 10 < anzahl)
printf("\nEs wurde eine falsche #Artikel eingegeben.");
} while(anzahl < 1 || 10 < anzahl);
for(int i = 0; i < anzahl; i++)
eingabe_artikel(&artikelliste[i], i);
int i;
for(strk_zgr = artikelliste, i = 0; strk_zgr < artikelliste + anzahl;
strk_zgr++, i++)
ausgabe_artikel(strk_zgr, i);
}
void eingabe_artikel(artikel *strk_zgr_fp, int i_fp) {
printf("\nBitte den %d. Artikel eingeben: ", ++i_fp);
printf("\nNummer: ");
scanf("%d", &strk_zgr_fp->nummer);
printf("Bezeichnung: );
scanf("%s", strk_zgr_fp, (int)sizeof(strk_zgr_fp->bezeichnung - 1)); /* <-- */
printf("Menge: ");
scanf("%d", &strk_zgr_fp->menge);
float preis;
printf("Preis: );
scanf("%f", &preis);
strk_zgr_fp->preis = preis;
}
void ausgabe_artikel(artikel *strk_zgr_fp, int i_fp) {
printf("\n%d. Artikel: ", ++i_fp);
printf("\nNummer:\t%d", strk_zgr_fp->nummer);
printf("\nBezeichnung:\t%s", strk_zgr_fp->bezeichnung);
printf("\nMenge:\t%d", strk_zgr_fp->menge);
printf("\nPreis:\t%.2f EUR\n", strk_zgr_fp->preis);
}
NetBeans Version
Complier Version
Many problems in the code. Please at least fix the missing ending quotes on the printf() calls.
Now to the beef:
1) Your structure is wrong. 'Bezeichnung' is defined as a single character, not a string.
typedef struct {
int nummer;
char bezeichnung[100];
int menge;
float preis;
} artikel;
2) You cannot use scanf() in the way you did. If you want to limit the input length (which always is a good idea), you need to pass the maximum length into the format string.
Do you nee to use scanf()?? Because it gets messy from here on....
As your maximum input length might be variable or subject to change (see 1.), you need to build the format string for scanf. Something like this:
char format_str[15];
format_str[0] = '%';
//Dont use itoa(), it is not C standard.
sprintf(&format_str[1], "%d", (int)sizeof(strk_zgr_fp->bezeichnung) - 1);
strcat(format_str, "s");
scanf(format_str, strk_zgr_fp->bezeichnung);
Hope that gets you going.
PS: You need to include string.h for strcat().
I tried it out and it worked fine for me. Not sure on this sprintf() function. Could you please explain why I'm supposed to use it? By now, I used this code: char format_str[20]; format_str[0] = '%'; strcat(format_str, "s"); printf("Bezeichnung: "); scanf(format_str, strk_zgr_fp->bezeichnung);
While that works, you are missing out on limiting the length of the user's input. That is why I proposed using sprintf() to create a (sub)string containing the maximal allowable length of the user input, depending on how large your 'bezeichnung' is defined in the struct. Suppose 'bezeichnung' has a limit of 100 characters, you would want to limit the input to 99 (+1 for the zero-termination), so you want a scanf format string like this: "%99s".
chux has provided a much more compact version of my three lines, but I think, in the beginning, you will have it easier to just assemble such format strings piece by piece, at the same time learning how to a) change individual characters in a string, how to use sprintf() in a basic way, and how to concatenate strings with strcat().
There was another example which I did and the course leader provided a scanf() function like this to read a string: scanf("%s", &(strk_zgr_fp->bezeichnung));. I thought when I'm reading a string the address operator isn't used. The only difference is the address operator now is used and the element was put into brackets.
Now, I think this is bad practice. It works, but is superfluous. Consider this small code snippet:
#include <stdio.h>
#include <stdlib.h>
struct test{
int i;
char a_str[10];
};
int main()
{
struct test a_test;
printf("Normal array adress taking: %p\n", a_test.a_str);
printf("Using '&' to take adress of array: %p\n", &(a_test.a_str));
return 0;
}
Hope that helps.

Abort trap when storing users input into two arrays

I am going to take in a users input consisting of their identification and their mark, separated by a space. The code compiles and I can enter answers at the prompt, however, at the end of the prompts (end of the first loop) I get an "Abort trap: 6" appearing.
I would appreciate it if you could help me find out why this comment is arising. I read that it could be from me overwriting over other memory, but it looks like my loops do not go beyond what I would want them to loop over (user gives me 10 answers).
I also added ampersands in front of the arrays in scanf, which I found odd to do, but the code did not compile otherwise.
include
int main (void){
char id[10];
int mark[10];
for (int i=0;i<10;i++){
printf("Enter ID and mark: \n");
scanf(" %s %d", &id[i], &mark[i]);
}
for (int i=0;i<10;i++){
printf("%c ",id[i]);
}
}
I think your ID reading is wrong, your IDs are string of 7 character length while your char id[10] is a string of 10 char ( where you intended to use a list of string ), you should use char *ids[10] instead.
char *ids[10] = { NULL }; // list of 10 string, initialized to NULL
int mark[10];
for (int i=0;i<10;i++){
...
char* id=malloc(8*sizeof(char)); // allocate a new string to store
scanf( "%7s %d\n", id, &mark[i] ); // check the result of the scanf to ensure you got the correct input
ids[i] = id; // store the string at position in the list
}
for (int i=0;i<10;i++){
printf("%s\n", ids[i]);
}
Also using a debugger like GDB would help you pinpoint where is the error happening in your code. And probably help you figure out your mistake.

Searching for a character in an array by incrementing a pointer?

So the function I declared doesn't seem to working as intended, and even so, I don't think that's the proper way to compare characters by incrementing the pointer, so I'm generally lost here. To be honest, pointers have always confused me and I really need to learn how to use them if I am going to get better at C. Thanks anyone for any help!
Here's the code I have, and if this helps, the purpose of the program is for you to enter a line of text, enter a single character to search in that line of text, and then find those characters using CharIsAt. (Will add the following later) the values stored in "found" will then be printed as well.
#include <stdio.h>
#define SIZE 41
int CharIsAt(char *pStr,char ch,int loc[],int mLoc);
int main(void){
char array[SIZE],search;
int found[SIZE],chars;
printf("Enter a line of text(empty line to quit): ");
while (fgets(array,SIZE, stdin)!=NULL && array[0]!='\n')
{
printf("Enter a character to search: ");
search=getchar();
chars=CharIsAt(array,search,found,SIZE);
}
return 0;
}
int CharIsAt(char *pStr,char ch,int loc[],int mLoc){
//Searches for ch in *pStr by incrementing a pointer to access
//and compare each character in *pStr to ch.
int i,x;
for (i=0;i<mLoc;i++){
if (strcmp(pStr[i],ch)==0){
//Stores index of ch's location to loc
loc[i]=pStr[i];
x++;
}
}
//Returns the number of times ch was found
return x;
}
EDIT: Flipped sign around in the for loop. Now the program gives me a "stopped working" error.

Program crashes when trying to scan strings into array

I am writing a program to intake exactly 5 peoples last names and their votes. Which will display the names of the people entered, the corresponding votes, and also the winner.
I need the names of the people into one array of strings. That is where the program crashes. Not sure if I can modify this to make it work or if I need to redo it.
the malloc function seems to be a recurring fix for this type of problem ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int TotalVotes(int voteArray[],int size)
{
int Sum=0;
for (int i=0;i<size;i++)
{
Sum+=voteArray[i];
}
return Sum;
}
int Winner(int voteArray[],int size)
{
int max;
max=0;
if (voteArray[1]>voteArray[max])
max=1;
if (voteArray[2]>voteArray[max])
max=2;
if (voteArray[3]>voteArray[max])
max=3;
if (voteArray[4]>voteArray[max])
max=4;
return max;
}
void main()
{
char nameArray[5];
int voteArray[5],Total,winner;
for (int i=0;i<5;i++)
{
voteArray[i]=0;
}
for (int j=0;j<5;j++)
{
printf("Enter the name of the candidate number %d\n",j+1);
scanf("%s",nameArray[j]);
printf("Enter that persons number of votes\n");
scanf("%d",&voteArray[j]);
}
Total=TotalVotes(voteArray,5);
winner=Winner(voteArray,5);
printf("%s\t%s\t%s\n","Candidate","Votes Received","% of Total Votes");
for (int y=0;y<5;y++)
{
printf("%s\t%d\t%0.2f\n",nameArray[y],voteArray[y],(float)voteArray[y]/Total);
}
printf("The Winner of The Election is %s\n",nameArray[winner]);
}
char nameArray[5]; is should be like char nameArray[5][20];
Yeah, in C, strings are represented by character arrays (char* or char[]).
Also, you should get fgets instead of scanf with strings for two reasons:
Fgets helps prevent buffer overflow because it knows the size of the string in advance.
Fgets will always run because it does not leave characters in the input buffer like scanf does.
The prototype for fgets looks somewhat like this (you can use stdin for the FILE pointer to read in from the keyboard, but realize that fgets keeps newlines):
fgets( char *output_variable, unsigned int string_length, FILE *input_file );
Also, if you use scanf, you should do a lot more error checking for invalid input.

How to find the length of a number in C? [duplicate]

This question already has answers here:
How do I determine the number of digits of an integer in C?
(20 answers)
Closed 8 years ago.
The program below is sufficent enouhgh to find the length of any string length that is given to the input, however, i need to find the length of an integer variable, rather than a string.
Entering a number to this does work, but not if i scan s as a int type.
int main()
{
char s[1000];
char i;
int u=5;
do
{
char s[1000];
char i;
int u=5;
system("cls");
printf("Enter a string: ");
scanf("%s",s);
for(i=0; s[i]!='\0'; ++i);
printf("Length of string: %d",i);
getch();
}
while(u==5);
getch();
}
So all i need is either this little program modified to accept intger variables, or a way to transform a calculated int variable into a string.
Any ideas?
Edit: Length = Amount of characters so 25 has 2, 3456 has 4 etc
Either use itoa to convert the integer to string and then use your code to calculate the length or
int i;
for (i=0; num!=0; i++, num=num/10){}
should give you the length of the number in i.
I guess the above example should work fine for integers also. Say if my string is 12345 then I will get 5 as my answer.
However, what else you can do is, input an integer, say i and then do the following.
while(i!=0){
length++;
i = i/10;
}
Here, I am considering i is an integer variable and not a character array.
You can use log10 and ceil functions from math.h instead.
int length = (int)(number ? log10(number) + 1 : 1);

Resources