I have created the following program which allows a user to guess a word 3 times before ending the program. I'm using a function to read the users input. When I compile the program I get the error 'expected expression before char'. Some feedback would be great thanks!
#include <stdio.h>
#include <string.h>
void get_user_input(char *guess[10]);
void get_user_input(char *guess[10])
{
printf("Please guess the word: \n");
scanf("%s", guess);
}
int main(void)
{
const char secret[10] = "pink";
char guess[10];
int i;
for (i=0; i < 3; i++)
{
get_user_input(char *guess[10]);
if (strcmp(secret, guess)==0)
{
printf("Your guess was correct");
return 0;
}
else
{
printf("Your guess was incorrect. Please try again\n");
}
}
return 0;
}
You have an extra char here:
for (i=0; i < 3; i++)
{
get_user_input(char *guess[10]);
Just get rid of it. You just need to pass the variable in.
get_user_input(guess);
EDIT :
The other problem seems to be this function:
void get_user_input(char *guess[10]);
change it to this:
void get_user_input(char *guess)
{
printf("Please guess the word: \n");
scanf("%s", guess);
}
and it should work. However, be aware that you run the risk of overrunning your guess array.
Inside the loop, write
get_user_input(guess);
instead of
get_user_input(char *guess[10]);
.
In addition, you should delete the useless prototype
void get_user_input(char *guess[10]);
and change the following function's signature to
void get_user_input(char * guess)
to let a pointer to the first char of the array be passed instead of a pointer to a pointer to the first char which will not compile. A side issue is that char *guess[10] means an array of 10 pointers to char.
PS: It helps to post the offending line number in addition to the error message.
PPS: You have a buffer overrun memory error if the use enters long answers. You can use fgets to avoid this.
Related
I need to read a word from main function and convert the characters in UCASE if the first character is LCASE and vice versa using the user defined function.I tried ways for returning the array from function but still I am lacking some core ideas. Please debug this program and explain the way it works.
#include <stdio.h>
#include <string.h>
int* low (char str)
{
int i;
for (i=1; i<strlen(str);i++)
{
if(str[i]<91)
{
str[i]=str[i]+32;
}
else
{
}
}
return &str;
}
int* high (char str[50])
{
int i;
for (i=0; i<strlen(str);i++)
{
if(str[i]>91)
{
str[i]=str[i]-32;
}
else
{
}
}
return &str;
}
void main()
{
char str[50];
char* strl;
printf("Enter any string....\n");
scanf("%s",str);
if (str[0]<91)
{
*strl=low(str);
}
else
{
*strl=high(str);
}
printf("Converted string is %s.",*strl);
}
There is already a problem here:
So if you are saying this code is perfect and you want us to debug it and explain how (on earth) this works, then here you go.
In function int* low (char str), you have if(str[i]<91). Thats a problem right there. str is a char received as an argument, and hence str[i] is a straight compile-time error.
Another one to deal with is the return statement.
You have a statement:
return &str;
which would return the address of str, which by the way is a char, whereas function low is supposed to return a pointer to an int.
The same is applicable to high function as well.
Suggestion: Leave aside this bad code and get a beginner level C programming book first. Read it and the try some codes out of it.
A few inputs for improvement: (Which you may not comprehend)
change
void main()
to
int main(void)
Why? Refer this legendary post: What should main() return in C and C++?
Secondly, int both functions you are using strlen() in loop which will always return a fixed value. So, instead of
for (i=0; i<strlen(str);i++)
I'd suggest,
size_t strlength = strlen(str);
for (i=0; i < strlength; i++)
You can try the code and method as below:
#include <stdio.h>
#include <string.h>
char* caseConverter (char *str)
{
int i;
for (i=0; i<strlen(str);i++)
{
if(str[i]>=65 && str[i]<=90)
{
str[i]=str[i]+32; //To lower case
}
else if((str[i]>=97 && str[i]<=122))
{
str[i]=str[i]-32; //To upper case
}
else
printf("%c is not an alphabet \n",str[i]);
}
return str;
}
void main()
{
char inputStr[50]= "Stubborn";
char* opStr= caseConverter(inputStr);
printf("Converted string is %s",opStr);
}
I have an assignment where I have to print a users age and name based on their input.
Here is the code:
#include <stdio.h>
#include <string.h>
void GetUserInfo(int* userAge, char userName[]) {
printf("Enter your age: \n");
scanf("%d", userAge);
printf("Enter your name: \n");
scanf("%s", userName);
return;
}
int main(void) {
int userAge = 0;
char userName[30] = "";
//insert code here
printf("%s is %d years old.\n", userName, userAge);
return 0;
}
I can't change any code except for the //insert code here.
I'm pretty sure that I have to call the function but I can't figure out what parameters to pass the function. I tried
void GetUserInfo(int* userAge, char userName[]);
but as you can probably figure out it passes an empty string for a name and 0 as the age due to the initializations in the main().
The parameters you need for the function are a pointer to int and a pointer to char.
GetUserInfo(&userAge, userName);
The "&" operator gives you the address of the userAge variable that can be used as a pointer.
The compiler will take care of passing the start of the userName array of chars as second parameter.
I'm having a bit of trouble with using structs inside functions.
The program is meant to:
Create an array containing five structures of type Person
Allow the user to enter the datatypes through use of functions.
Print the five entered people one by one.
While point 1 and 3 work fine, it's point 2 that I'm having issues with. The name will enter and print just fine, but regardless of what I enter into scanf it returns and prints '-858993460'.
int calls = 0;
typedef struct person {
char name[20];
int bYr;
}Person;
int main(int argc, char** argv) {
Person psn[5];
for (int i = 0; i < 5; i++) {
printf("Please enter the name and birthyear of person %d.", i+1);
personName(psn[i].name);
personBirthyear(psn[i].bYr);
}
for (int i = 0; i < 5; i++) {
printPerson(psn[i]);
}
getchar();
return 0;
}
int personBirthyear(int birthyear) {
printf("\nBirthyear: ");
scanf("%d", &birthyear);
getchar();
return birthyear;
}
char* personName(char* pername) {
printf("\nName: ");
fgets(pername, 20, stdin);
return pername;
}
void printPerson(Person prsn) {
printf("Person %d:\nBirthyear: %d\nName: %s\n", calls+1, prsn.bYr, prsn.name);
calls++;
}
Easy enough: you are not updating a Person' year, but you are passing it as a copied argument (you copy an int in personBirthyear and a pointer to a char in personName).
Thus:
personName(psn[i].name); // works
personBirthyear(psn[i].bYr); // fails
You need to pass the address of year, and work with pointers here:
int personBirthyear(int* birthyear) {
printf("\nBirthyear: ");
scanf("%d", birthyear);
getchar();
return *birthyear;
}
Or, you could also remove the birth year:
int personBirthyear() {
int birthyear;
printf("\nBirthyear: ");
scanf("%d", &birthyear);
getchar();
return birthyear;
}
Then: psn[i].bYr = personBirthyear();
In any case, you don't check the result of scanf; thus you don't know if you actually read a number. You should check it:
int n = scanf("%d", &birthyear);
getchar();
if (n != 1) return -1;
return birthyear;
The getchar is still mandatory to "clear" away the character that made scanf fail (otherwise, it would be reread again and again...).
you have some problems in your code :
You are not receiving a output while returning from function.
Without function declaration compiler will confuse about function return type.
you should know if you want to accept modified data between function call, data should provide as pass by reference. in your program, you give data to personBirthyear() function as call by value.
I tried to write a function, that get a number of candidates betwen 10 to 60,000,
and gets a name for each candidate...
This is what I wrote:
/********** Headers **********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
/********** Consts **********/
const number_candidates;
/********** Functions **********/
void get_candidates(char *arr[256][256])
{
int counter = 1, i = 0, j =0;
int temp = 0;
printf ("Please enter the number of candidates: \n");
scanf ("%d", &temp);
while (temp < 10 && temp > 60000)
{
printf ("Please enter the number of candidates: \n");
scanf ("%d", temp);
}
const number_candidates = temp;
while (counter < number_candidates + 1)
{
printf ("Please enter the %d name: \n", counter);
fgets (arr, 256, stdin);
counter++;
}
}
int main(int argc, char *argv[])
{
int i = 0;
char can_names[256][256];
get_candidates(&can_names);
system("PAUSE");
return 0;
}
There is an error in getting the names into the arr...
You should avoid using arguments like this one: char *arr[256][256] ... what's the point of it? You should think about what your function will do. You want it to load names of candidates right? So you could define struct candidate with an attribute name within it:
typedef struct candidate{
char name[256];
} Candidate;
Another thing: why are you passing an address of your array to this function? You just want your array to be filled with data, you won't work with an array itself, thus it's enough to pass an array, not an address of it.
Then prototype of your function could be changed to void get_candidates(Candidate* candidates) which is much easier to read. And look how simple can usage of this function become:
Candidate candidates[256];
get_candidates(candidates);
And last thing: before you write function like that, try something simpler first (to find out what's happening there).
Here's an example:
#include <stdio.h>
typedef struct candidate{
char name[256];
} Candidate;
void get_candidates(Candidate* candidates){
scanf("%255s", candidates[4].name);
}
int main(int argc, char *argv[]){
Candidate candidates[256];
get_candidates(candidates);
printf("%s\n", candidates[4].name);
return 0;
}
In case you don't know the count of candidates before calling get_candidates, then it's better to change the prototype of this function to Candidate* get_candidates() so that it's clear that this function creates an array:
// caller is responsible for calling free on return value
Candidate* get_candidates(){
Candidate* candidates;
int count = 50; // here you found out the count
candidates = malloc(count*sizeof(Candidate));
fgets(candidates[4].name, 255, stdin);
return candidates;
}
int main(int argc, char *argv[]){
Candidate* candidates = get_candidates();
printf("%s\n", candidates[4].name);
free(candidates);
return 0;
}
You should call:
counter = 0;...fgets (arr[counter], 256, stdin);
You need walk one step for each loop.
Have a look at the documentation for scanf which indicates that variables need to be passed as a pointer as you did the first time you call scanf. Then have a look at your second call to scanf...
You're currently only assigning names to the first string in your array over and over again. Look at that while loop and in particular, how you're passing in the 'arr' variable. Have a look here for some inspiration.
To print out all of the names you need to loop over the array. You can find some examples of printing a list of strings here and here.
A few things are wrong:
First, you need space for 60000 names, yet you only allocate enough for 256. OK, we change
char can_names[256][256];
to
char can_names[60000][256];
and get... a segmentation fault, probably. That's because the array is using too much stack space. Change it to
static char can_names[60000][256];
so it's not on the stack.
Second, there's no need to take the address of the array - it's already passed as a pointer. Your function call changes to
get_candidates(can_names);
and the function signature is
void get_candidates(char arr[60000][256])
Third, you need a loop to read the entries one at a time. A for loop is easier to read:
for (counter = 0; counter < number_candidates; counter++)
{
printf ("Please enter the %d name: \n", counter);
fgets (arr[counter], 256, stdin);
}
Fourth, the condition
while (temp < 10 && temp > 60000)
should be
while (temp < 10 || temp > 60000)
(how can a number be both less than 10 and greater than 60000?) Once this is fixed, you can remove the initial read of temp since the loop will run at least once. Note that if you type a letter instead of a number now, the program will go into an infinite loop (it will repeatedly read the letter). Fixing this is left as an exercise.
Fifth, you don't need any headers except stdio.h. Also, the i and j variables are unused.
Edit: missed the scanf error. scanf takes addresses as parameters. it makes sense too: scanf needs somewhere to store a value, it doesn't care about the current value. So the call to scanf should be:
scanf ("%d", &temp);
Don't know if this would help but have a look at the code below.
It works dynamically ie. it allocated memory for desired no of candidates rather than assuming 60,000 of them.
/*
* Write a function, that get a number of candidates betwen 10 to 60,000, and gets a name for each candidate
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 256
int main(int argc, char*argv[]){
int i,n;
char **s;
printf("Enter the total number of candidates\n");
scanf("%d",&n);
//error condition
if(n<10 || n>60000){
printf("Sorry number of candidates should be between 10 to 60,000\n");
return -1;
}
//allocate memory
s = malloc(sizeof(char*)*n);
//get the data
for(i=0;i<n;i++){
s[i] = calloc(MAX,sizeof(char));
printf("Enter the candidate number %d's name:\n",i+1);
//fgets(s[i],MAX,stdin);
scanf("%s",s[i]);
}
//Display the data
printf("\nDetails of all the Candidates\n\n");
for(i=0;i<n;i++){
printf("Candidate number %d's name:%s\n",i+1,s[i]);
}
//Free the memory
for(i=0;i<n;i++){
free(s[i]);
}
free(s);
return 0;
}
I had a problem with fgets it was skipping the first candidate info. Any help would be appreciated.. I tried flush(stdin) but did not solve the issue.
i have the following problems in C programming.
I have an array of strings stored as words[10][50]. I want to extract each of the string from the array and then pass it on to another function. I tried on the following:
#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
int Check_Anagram(char*,char*);
void main()
{
char words[10][20];
int i;
int flag;
for(i=0;i<3;i++)
{
scanf("%s\n",words[i][20]);
}
for(i=1;i<10;i++)
{
flag = Check_Anagram(words[i][20],words[i-1][20]);
}
getch();
}
int Check_Anagram(char *a,char *b)
{
printf("%s %s\n",a,b);
return 1;
}
This creates an exception during compiling.
Now i think that when i use the "printf" statement then this nomenclature works fine i.i words[i] prints the string "i" from the double dimension words array. When i try to do the same thing with the check function then the error occurs.
Can soemone point me how to do this passing ?
P.S. Please ignore any error in efficiency of program and likewise. I need your help and this is just a test program at learning string passing to a function
Thanks
You're passing words[i][20]. You need to pass words[i] instead in both loops. Try this:
for(i = 1; i < 3; i++) /* i < 3 */
{
flag = Check_Anagram(words[i], words[i-1]);
}
Another problem is that you're reading 3 strings and trying to print 10. So when you pass words[3] it contains garbage: printf tries to print garbage which need not be 0-terminated.
In the first for loop, when i is 0, you're pointing to words[-1], that's your exception.
flag = Check_Anagram(words[i][20],words[i-1][20]);
You are passing the 21st letter of each word the Check_Anagram. Instead you should pass the words themselves:
flag = Check_Anagram(words[i],words[i-1]);
You have a similar problem where you use scanf. To read a line from the console to each word you would use:
for(i=0;i<10;i++)
{
scanf("%s\n",words[i]);
}
#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
int Check_Anagram(char [],char []);
void main()
{
char words[10][20];
int i;
int flag;
for(i=0;i<3;i++)
{
scanf("%s\n",words[i]);
}
for(i=1;i<10;i++)
{
flag = Check_Anagram(words[i],words[i-1]);
}
getch();
}
int Check_Anagram(char a[],char b[])
{
printf("%s %s\n",a,b);
return 1;
}
I finally got it corrected thanks to the help of all users.
I have posted the corrected code for people who are struggling with passing of string extracted from an array of strings to another function. hope it helps.