Passing String to Main from a function - c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void get_name();
void display_name(char *fullname);
int main(void)
{
char first[80];
char second[80];
char *fullname[80];
get_name();
display_name(*fullname);
system("pause");
return 0;
}
void get_name()
{
char first[80];
char second[80];
char *fullname[80];
printf("Please enter first name: ");
scanf("%s", &first);
printf("\nPlease enter last name: ");
scanf("%s", &second);
strcpy(*fullname, first);
strcat(*fullname, " ");
strcat(*fullname, second);
printf("\n\nFull name is : %s ", *fullname);
}
void display_name(char *fullname)
{
int index;
char check;
int count=0;
printf("\n\nFull name is : %s ", fullname); //check to see if string is passes correctly
for(index=0; fullname[index] != '\0'; index++)
{
check=fullname[index];
if(check != ' ')
{
count++;
}
}
printf("\n\nNumber of characters in string is: %i\n", count);
}
im trying to send the string from get_name() to display name to count the number of characters. Everytime i pass the string, its comes out as gibberish. Am i passing wrong? I need to use one function to get the first and last name and concatenate the full name, then use another function to count the number of characters.

You're using pointers and scanf quite wrongly.
First of all scanf argument to for %s is supposed to be an array of characters. Remember that the array is in fact the pointer to the array.
Second you declare fullname to be an array of 80 pointers which is probably not what you want to do. Especially when you don't allocate the space for the string.
Instead it should be something like:
void get_name()
{
char first[80];
char second[80];
char fullname[80]; // an array of chars instead of pointers
printf("Please enter first name: ");
scanf("%s", first); // not taking the address of first - is already an address
printf("\nPlease enter last name: ");
scanf("%s", second); // not taking the address of second - is already an address
strcpy(fullname, first); // don't dereference fullname
strcat(fullname, " "); // don't dereference fullname
strcat(fullname, second); // don't dereference fullname
printf("\n\nFull name is : %s ", fullname); // don't dereference fullname
}

The declarations of variables are local to the scope where they are declared.
IOW when you declare first, second and fullname in your function get_name, they are local to that function. In order to pass the value outside of the function you have two, no three ways to do this starting with the worst way:
(1) declare the variable global, i.e. outside of main then share that variable in your function(s).
(2) declare the variable in main but pass it to the function who then fills in the string
int main()
{
char fullname[80];
get_name(fullname,sizeof(fullname)); // good to tell function avail size
...
void get_name(char* fullname, size_t length)
{
...
(3) Allocate memory on the heap, heap memory can be passed around between functions via a pointer
int main()
{
char* fullname = NULL;
get_name(&fullname);
...
void get_name(char** fullname)
{
*fullname = malloc(80);
...
EDIT
In order to read strings from the keyboard it is better to use fgets()
char buffer[128];
if (fgets(buffer,sizeof(buffer),stdin) != NULL) {
// remove the \n
char* p = strchr(buffer,'\n');
if ( p != NULL ) {
*p = '\0';
}
}
Using scanf reading from the keyboard is to be avoided, if you need to extract information use instead sscanf on the string read with fgets

Related

why does my program not print out the final result?

why when i run this code to take in a string input by the user why does it not print out the final result ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Function Declerations */
/* Global Variables */
char *text = NULL;
int size;
int main(){
/* Initializing Global Variables */
printf("enter a number limit for text: ");
scanf("%d", &size);
/* Initial memory allocation */
text = (char *) malloc(size * sizeof(char));
if(text != NULL){
printf("Enter some text: \n");
scanf("%s", &text);
// scanf(" ");
// gets(text);
printf("You inputed: %s", text);
}
free(text);
return 0;
}
/* Function Details */
in fact the end result looks like this
enter a number limit for text: 20
Enter some text:
jason
text is already a char *, so you don't have to pass &text to scanf, but only text.
scanf takes a pointer as argument in order to modify the pointed value, but if you pass a char ** as an argument, you will modify the pointer to the string instead of the pointed string
you just have to remove the address from &text because text is a pointer and the string always pointe to the first character.

Just first alphabet is showing in the output.[char type]

When I give the input then only first alphabet is showing.
I want to print the complete name which is I just entered.
#include <stdio.h>
int main()
{
char name;
char grades;
int i;
printf("Name of the Student:");
scanf("%c",&name);
printf("Name your Just entered is : %c",name);
return 0;
}
I agree with the others - but add some error checking and ensure no buffer overruns i.e
#include <stdio.h>
int main() {
char name[101];
printf("Name of the student:");
if (scanf("%100s", &name) == 1) {
printf("Name you just entered: %s\n", name);
return 0;
} else {
printf("Unable to read name of student\n";
return -1;
}
}
EDIT
As you have edited the question so that it does not have the same meaning as before I will leave my previous solution here.
But what you want is to use fgets - this allows for white space in the name
ie.
#include <stdio.h>
int main()
{
char name[100];
printf("Name of student:");
fflush(stdout);
fgets(name, 100, stdin);
printf("Students name is %s\n", name);
return 0;
}
Replace char name; with char name[100];. This will define name as array of chars, because you handled with it as single character.
For scanf replace it with scanf("%s",&name[0]);, and printf with printf("Name your Just entered is : %s",name);. %s means string, so it will scan whole string, not just single character. In scanf &name[0] points to beginning of array.
You need to scanf into an array, rather than into a single character:
#include <stdio.h>
int main() {
char name[100];
printf("Name of the student:");
scanf("%s", &name);
printf("Name you just entered: %s\n", name);
}
You are trying to store a array of characters(string) in a character. So only the first character is taken.To rectify this initialize the name as:
char name[40];
take input as :
scanf("%s",name);
and print as:
printf("name is %s",name);
name is a char and scanf will only catch one character when you use %c. You can use a char array to store the name instead :
char name[40];
/* edit the size for your need */
Also edit your scanf and printf to use a %s
You are reading (and printing) a single char using %c. If you want to handle stirngs, you should use a char[] and handle it with %s:
#include <stdio.h>
int main()
{
char name[100]; /* Assume a name is no longer than 100 chars */
char grades;
int i;
printf("Name of the Student: ");
scanf("%s",&name);
printf("Name your Just entered is : %s",name);
return 0;
}

char pointers: invalid conversion from 'char*' to 'char'?

I cut out all the unnecessary code so no one gets too bored with my question... So I cant get the char array to work! on the last few lines of
*whatname = guyname;
*whatlastname = lastname;
I get an error saying invalid conversion from 'char*' to 'char'. Help would be much appreciated!
#include <stdio.h>
#include <ctype.h>
#include <string.h>
void getname(char *whatname, char *whatlastname);
int main()
{
int option = 0;
char guyname = 'x';
char lastname = 'x';
bool name_entered = false;
do{
printf("1. Enter name.\n");
printf("2. Enter exam scores.\n");
printf("3. Display average exam scores. \n");
printf("4. Display summary. \n");
printf("5. Quit. \n");
scanf("%i", &option);
if( option == 1 )
{
name_entered = true;
getname(&guyname, &lastname);
}
else if( option == 4 )
{
{
printf("%s %s based on your exam scores of \n",guyname, lastname);
}
else
{
printf("Please enter your name in option 1 and you exam scores in option 2 before continuing.\n");
}
}
else if( option == 5 )
{
printf(" Come back with a better grade next time.");
break;
}
}while (!(option >5 || option <1));
return 0;
}
void getname (char *whatname, char *whatlastname)
{
char guyname[32];
char lastname[32];
printf("Enter your first and last name : ");
scanf("%s %s", &guyname, &lastname);
guyname[0] = toupper( guyname[0] );
int len = strlen(guyname);
for(int i=1; i<len ; i++)
{
guyname[i] = tolower( guyname[i]);
}
lastname[0] = toupper( lastname[0] );
int len1 = strlen(lastname);
for(int k=1; k<len1; k++)
{
lastname[k]= tolower( lastname[k]);
}
printf("Your name is %s %s\n", guyname, lastname);
*whatname = guyname;
*whatlastname = lastname;
}
Dealing with char, char*, and char [] in C is a little confusing in the beginning.
Take a look at the following statements:
char str1[] = "abcd";
char const* str2 = "xyz";
char* cp = str1;
char c = *cp;
The first statement and the second statement are identical in their behavior. After the first statement is executed, str1 points to a location that contains 4 characters, in consecutive order. If you think of the memory locations for the string, you might see something like:
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
str1 points to the address where a is stored. There is a similar arrangement for storing the string "xyz" and str2 points to the address where x is stored.
In the third statement, you are creating cp and making it point where str1 is pointing. After that statement, both cp and str1 point to the same string - "abcd".
*cp evaluates to the character that exists at the address that cp points to. In this case, it will be 'a'.
In the fourth statement, you are initializing c with 'a', the character that exists at the address pointed to by cp.
Now, if you try a statement
*cp = str2;
it is a compiler error. *cp simply dereferences the address of cp. You can put a char at that location, not str2, which is a char*.
You can execute
*cp = *str2;
After that, the objects in the memory that str1 and cp point to will look like:
+---+---+---+---+
| x | b | c | d |
+---+---+---+---+
If you want to copy the string from the address pointed to by str1 to the address pointed to by cp, you can use the standard library function strcpy.
strcpy(cp, str2);
You have to be careful about using strcpy because you have to have enough valid memory to copy to. In this particular example, if you tried
char str3[2];
strcpy(str3, cp);
you will get undefined behavior since there isn't enough memory in str3 to be able to copy "abcd".
Hope that made sense.
Here's a modified version of your code that should work:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
void getname(char *whatname, char *whatlastname);
int main()
{
int option = 0;
char guyname[32];
char lastname[32];
bool name_entered = false;
do{
printf("1. Enter name.\n");
printf("2. Enter exam scores.\n");
printf("3. Display average exam scores. \n");
printf("4. Display summary. \n");
printf("5. Quit. \n");
scanf("%i", &option);
if( option == 1 )
{
name_entered = true;
getname(guyname, lastname);
}
else if( option == 5 )
{
printf(" Come back with a better grade next time.");
break;
}
}while (!(option >5 || option <1));
return 0;
}
void getname (char *whatname, char *whatlastname)
{
char guyname[32];
char lastname[32];
printf("Enter your first and last name : ");
scanf("%31s %31s", guyname, lastname);
guyname[0] = toupper( guyname[0] );
int len = strlen(guyname);
for(int i=1; i<len ; i++)
{
guyname[i] = tolower( guyname[i]);
}
lastname[0] = toupper( lastname[0] );
int len1 = strlen(lastname);
for(int k=1; k<len1; k++)
{
lastname[k]= tolower( lastname[k]);
}
printf("Your name is %s %s\n", guyname, lastname);
strcpy(whatname, guyname);
strcpy(whatlastname,lastname);
}
lot of things wrong here. You need to think about where the two string are going to be stored.
You are trying to return variable on the stack of getname - even if you fix the C code that wont work.
a) getname needs to be getname(char**, char**)
b) whatname and whatLastname need to be char *
c) call getname with (&whatname &whatLastName)
d) strdup the strings in getname into the two params (*whatname,...)
You have a pair of values in the main which are single characters.
You're passing in pointers to those characters, then dereferencing them (which gives you single characters again), then trying to assign character pointers to them. That definitely isn't going to work.
Even if you did,
whatname = guyname;
whatlastname = lastname;
which would be type-correct, it wouldn't do what you seem to want, which is to change the values in the calling function. It would only change the values of the argument variables in the subroutine.
If you're trying to return two strings found in the subroutine, change the calling code's variables to:
char *guyname = "x";
char *lastname = "x";
and change the function arguments to
void getname (char **whatname, char **whatlastname)
Then your assignment will be type-correct, and will change the pointers in the calling function.
There shouldn't be & in scanf of string.
first of all, using * on a pointer will dereference it (you did it on the last two lines)
secondly, you are sending to the function a pointer to a single char, not an array of chars so if you will write to its memory you will write on some other variable's memory.
What you should have done is declaring guysname and lastname as char arrays
char guysname[32];
and in your function just read your input directly into the parameters you recieve:
scanf("%s %s", whatname, whatlastname);
replace all instances of guysname and lastname for whatname and whatlastname. get rid of the last lines.
If you want to keep the char arrays inside the function anyway, just use
strcpy(whatname,guysname)
and the same for the last name.
You can't assign a char value to a char pointer, and you can't dereference an Lvalue.
whatname = &guyname;
whatlastname = &guylastname;
This is what you're looking for. However, it appears that you're just starting to play with pointers, and you may need to read up on them a little more before you start experimenting.

How to take first letter from C string?

I want to take the first letter from my firstname string variable and add it to the second letter of the lastname variable.
My program so far is:
#include <stdio.h>
main() {
char firstname [256];
char lastname [256];
printf("What's your first name?: ");
scanf("%c",&firstname);
printf("What is your last name? ");
scanf("%s",&lastname);
printf("\nYour school.edu e-mail address is: %c%s2#school.edu",firstname,lastname);
return 0;
}
However, I would like for my code to take the first initial (the first letter of the first name) and store it into the firstname variable.
As strings are array of characters, you need to take the first element from the array:
char firstname_initial;
firstname_initial = firstname[0]
Also note that since lastname and firstname are buffers, you don't need to pass a pointer to them in scanf:
scanf( "%s", firstname );
scanf( "%s", lastname );
And one last thing - scanf is a dangerous function and you should not use it.
Suppose the user types:
Michael
in response to the first prompt. The %c format reads the M; the %s format reads ichael without bothering to get any new data.
Also, you should not be passing &firstname or &lastname; you should be passing just firstname and lastname to scanf(). The difference is in the type; with the ampersand, you're passing a char (*)[256] which is not the same as the char * that scanf() expects. You get away with it, but 'get away with it' is the operative term.
Use a %s format (or, better, %255s format) for the two scanf() calls. Then pass firstname[0] and lastname to printf(). You might want to think about using tolower() from <ctype.h> on the first letter, and maybe on the last name too.
This is a reasonable approximation to a good program:
#include <stdio.h>
int main(void)
{
char firstname[256];
char lastname[256];
printf("What's your first name? ");
if (scanf("%255s", firstname) != 1)
return 1;
printf("What's your last name? ");
if (scanf("%255s", lastname) != 1)
return 1;
printf("Your school.edu e-mail address is: %c%s2#school.edu\n",
firstname[0], lastname);
return 0;
}
It avoids quite a lot of problems, one way or another. It is not completely foolproof, but most people won't run into problems with it.
I think you want the variable firstname to store only the initial.
So that firstname act like string.
firstname[1] = '\0'; //mark the end of string on second character
printf("\nYour school.edu e-mail address is: %s%s2#school.edu",firstname,lastname);
#include <stdio.h>
#include<string.h>
main() {
char firstname [256];
char lastname [256];
char str [50];
printf("What's your first name?: ");
scanf("%s",firstname);
printf("What is your last name? ");
scanf("%s",lastname);
str = strcpy(str, firstname[0]);
str = strcpy(str,lastname[1]);
printf("\nYour school.edu e-mail address is: %s2#school.edu",str);
return 0;
}
Copy first char from c string
char extractedchar = '0';
extractedchar=myoldstring[0];
Note : the char '0' is there just to test later in the application
Assuming expected input:
fname = Batman
lname = Joker
Expected Output:
Your school.edu e-mail address is: BJBker2#school.edu
Try this:
void main( void )
{
char fname = 0;
char lname[256] = {0};
printf("Enter firstname\n");
scanf("%c", &fname);
printf("Enter lastname\n");
scanf("%s", lname);
lname[1] = fname;
printf("Your school.edu e-mail address is: %c%s2#school.edu\n", fname, lname);
return;
}

Storing Pieces of a String using Strtok

#include <stdio.h>
#include <math.h>
#include <string.h>
int main(void)
{
int menuswitch=1;
int amountofstudents;
int fname[50];
int lname[50];
int grade[50];
int i;
char studentinfo[100];
printf("Enter Amount of Students: ");
scanf("%d", &amountofstudents);
for (i=0;i<amountofstudents;i++)
{
gets(studentinfo);
strcpy(fname[i], strtok(studentinfo, " "));
strcpy(lname[i], strtok(NULL, " "));
strcpy(grade[i], strtok(NULL, " "));
}
Alright need a little using strtok. I am trying to store pieces of an input string to sort later. I was thinking of using strtok to break the string then placing each piece in the corresponding array. Yet, every time I try I get an error in Visual Studios saying Access Violation. Thanks for the help ahead of time
The error is
First-chance exception at 0x5120F7B3 (msvcr110d.dll) in Lab 2.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x5120F7B3 (msvcr110d.dll) in Lab 2.exe: 0xC0000005: Access violation reading location 0x00000000.
The input would be
FirstName Lastname 80(Grade)
One major problem is that you try to copy into integer values and not strings. Change the
integer arrays to arrays of strings:
...
char fname[50][100];
char lname[50][100];
char grade[50][100];
...
You also have a problem with the gets function (besides it being obseleted and should not be used), namely that the previous scanf doesn't remove the newline from the input buffer so the first gets call will see this empty newline and give you an empty line (which you do not check for).
This is simply solved by telling scanf to discard trailing whitespace by adding a space in the format string after the "%d":
scanf("%d ", &amountofstudents);
/* ^ */
/* | */
/* Note space */
Instead of gets, you should be using fgets:
fgets(studentinfo, sizeof(studentinfo), stdin);
And finally, always check for errors!
a potential issue is the scanf/gets combo. use instead fgets() and convert when appropriate to integer using atoi() it is also good to do a sanity check on what is returned from strtok (it is never good to assume anything about input)
char* token = strtok(studentinfo, " ");
if ( strlen(token) < sizeof(fname[i]) )
{
strcpy(fname[i], token);
...
you have also declared your strings as integer arrays, they should be char
e.g. char fname[50];
The problem you have is that you have declared three variables (fname, lname, and grade) as char[] (arrays) (well, that is the type you meant to use), but you want to prompt for and keep around a bunch of students information. And you later try to copy from strtok() into what you want to be a char[], but since you dereferenced fname[i] (lname[i], grade[i]), they are of type char, rather than char[].
You will need stdlib.h for exit,
#include <stdio.h>
#include <stdlib.h> //for exit
#include <string.h>
//#include <math.h> //you don't need this, yet
#define STUDLIMIT (100)
You can either create an array of fname[], lname[], grade[], (see here: http://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html),
int main(void)
{
//int menuswitch=1; //you aren't using this
int amountofstudents;
char studentinfo[100];
char fname[STUDLIMIT][50];
char lname[STUDLIMIT][50];
char grade[STUDLIMIT][50];
int ndx;
printf("Enter Amount of Students: ");
if( (fscanf(stdin,"%d ", &amountofstudents)<=0)
|| (amountofstudents<1) || (amountofstudents>STUDLIMIT) )
{
printf("need %d to %d studends\n",1,STUDLIMIT); exit(0);
}
for (ndx=0;ndx<amountofstudents;ndx++)
{
printf("Student: "); fflush(stdout);
fgets(studentinfo,sizeof(studentinfo),stdin);
strcpy(fname[ndx], strtok(studentinfo, " "));
strcpy(lname[ndx], strtok(NULL, " "));
strcpy(grade[ndx], strtok(NULL, " "));
}
}
Or you can create a struct(ure) to hold the entered student information, and instantiate an array of these student records, one for each student you enter and store,
typedef struct student
{
char fname[50];
char lname[50];
char grade[50];
} StudentObj;
int StudentCopy(StudentObj*sp,char*fname,char*lname,char*grade)
{
if(!sp || !fname || !lname || !grade ) return -1;
strcpy(sp->fname, fname);
strcpy(sp->fname, lname);
strcpy(sp->fname, grade);
}
StudentObj students[STUDLIMIT];
int main(void)
{
//int menuswitch=1; //you aren't using this
int amountofstudents;
char studentinfo[100];
char fname[50];
char lname[50];
char grade[50];
int ndx;
printf("Enter Amount of Students: ");
if( (fscanf(stdin,"%d ",&amountofstudents)<=0)
|| (amountofstudents<1) || (amountofstudents>STUDLIMIT) )
{
printf("need %d to %d studends\n",1,STUDLIMIT); exit(0);
}
for (ndx=0;ndx<amountofstudents;ndx++)
{
printf("Student: "); fflush(stdout);
fgets(studentinfo,sizeof(studentinfo),stdin);
strcpy(fname, strtok(studentinfo, " "));
strcpy(lname, strtok(NULL, " "));
strcpy(grade, strtok(NULL, " \n\r"));
StudentCopy(&(students[ndx]),fname,lname,grade);
}
}

Resources