No output during word swap - c

#include <stdio.h>
#include <ctype.h> /* for access to the toupper function */
void reverse_name(char *name);
int main(void)
{
char input[100];
printf("Enter a first and last name: ");
gets(input);
reverse_name(input);
return 0;
}
void reverse_name(char *name){
char *first = name;
char *see;
see = name;
while(*see != ' '){
}
while(*see != '\n'){
putchar(*see);
}
printf(", %c",*first);
}
I want this to happen: Enter a first and last name: Lloyd Fosdick
And the output be like this: Fosdick, L.
But after entering a first and last name, Lloyd Fosdick, the program doesn't give any answer and nothing happens? Whats wrong with the code?

You neither increment see nor check for 0 terminator in both of your while loops:
while(*see && *see != ' '){
see++;
}
while(*see && *see != '\n'){
putchar(*see);
see++;
}
gets() has been removed from C11 and you should never use it even if you are following older standards. Use fgets() instead.
This is by no means a complete fix. You'll have to ask yourself:
what if the input contains more than one space between the names?
what if the input contains more than two names?
What if there's no first name or last name?
etc.
You need to think about all these cases and handle them in your code.

You have an infinite loop
while(*see != ' '){}
You need to increment your pointer position.

I think that this is better code
(gets function is deprecated)
You read format code. their is space between firstName and secondName.
No infinite loops not loops at all.
int main(void)
{
char firstName[100];
char secName[100];
printf("Enter a first and last name: ");
scanf("%s %s",firstName,secName);
printf("%s ,%c",secName,firstName[0]);
return 0;
}

Related

read in input, then read in each char in c programming

I am working on a practice problem from my textbook by kernigan and ritchie (again for practice, not for credit).
The problem states to write a program that prints a histogram of the lengths of words in its input.
I want to do this by printing a "_" for every char that I read. However, I'm having a lot of trouble reading chars.
Right now, my program looks like this:
int main(){
int c;
char str[100];
scanf("%s", str);
printf("|");
while((c = getchar()) != EOF){
putchar(c);
printf("_");
}
printf("|");
return 0;
}
main compiles. However When I try to use it and give it a word (of any length), it simply prints:
|
_
and then the cursor moves right next to the underscore. What am I doing wrong? Why is the underscore printed after the "|" rather than next to it, as I didn't use \n ?
The output you see is because the scanf("%s", str) line captures the word you input up to the default delimiter character which is space and then goes on to print '|' character then attempts to read more from stdin.
If you had entered say mylong word do you like it? then ctrl-z
You would see:
| _w_o_r_d_ _d_o_ _y_o_u_ _l_i_k_e_ _i_t_?_
_^Z
|
This is because the characters word do you like it? are still in the stream to be processed.
If you only enter a single word without spaces then you will see what you observed.
The two lines:
char str[100];
scanf("%s", str);
could be removed and then you won't be capturing the word and doing nothing with it.
Alternatively, if you want to use scanf you could change like this:
#include <stdio.h>
int main(){
char str[100];
char* p = str;
scanf("%s", str);
printf("|");
while (*p != NULL) {
putchar(*p++);
printf("_");
}
printf("|");
return 0;
}
This code prints each character in str, interspersing with the _ character.

Findinga number in char

How can I check whether there are numbers in char provided by user in C language?
Last line of C code to change :):
char name;
do{
printf("What's your name?\n");
scanf("%s\n", name);
}
\\and here's my pseudocode:
while (name consist of a sign (0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9));
Here is a different approach that tests for specified chars in one function call.
#include <stdio.h>
#include <string.h>
int main()
{
char name[100];
char charset[]= "-+0123456789";
int len;
do {
printf("What's your name?\n");
scanf("%s", name);
len = strlen(name);
}
while (strcspn(name, charset) != len);
printf ("Your name is '%s'\n", name);
return 0;
}
You need to include ctype.h and use the isdigit() function.
But you also have another porblems in the posted code, "%s" specifier expects a char pointer, and you are passing a char, may be what you need is a char array like this
#include <stdio.h>
#include <ctype.h>
int main()
{
char name[100];
int i;
do {
printf("What's your name?\n");
scanf("%s\n", name);
}
/* and here's my pseudocode: */
i = 0;
while ((name[i] != '\0') &&
((isdigit(name[i]) != 0) || (name[i] == '-') || (name[i] == '+')))
{
/* do something here */
}
}
remember to include ctype.h and stdio.h
Use isdigit();
Prototype is:
int isdigit(int c);
Similarly to check the character is alphabet
Use
isalpha()
Once you get the string from the user, loop on it to search for correct input. (i.e. to see if there is a digit embedded in a collection of alpha characters). Something like this will work:
Assume userInput is your string:
int i, IsADigit=0;
int len = strlen(userInput);
for(i=0;i<len;i++)
{
IsADigit |= isdigit(userInput[i]);
}
The expression in the loop uses |=, which will detect and keep a TRUE value if any of the characters in the string are a digit.
There are many other methods that will work.
And the following family of character tests will allow you to do similar searches for other types of searches etc.:
isalnum(.) //alphanumeric test
isalpha(.) //alphabetic test
iscntrl(.) //control char test
isalnum(.) //decimal digit char test
isxdigit(.) //hex digit char test
islower(.) //lowercase char test
...The list goes on

Tokenizing a string

I am in the process of writing a C program that parses a string and tokenizing it by breaking the string characters into words that are seperated by white space. My question is when i run my current program:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char input[20];
printf("Please enter your word:\n");
scanf("%c", &input);
printf("%c", input[1]);
return 0;
}
If i was to enter the word "This", i would expect to get back "h" when i run the program but instead i get a downwards pointing arrow. However, when the input is set to print out input[0] i get back a "T".
Edit: I have modified my code so that it prints out the whole string now which i will show below
int main()
{
char input[20];
printf("Please enter your words:\n");
scanf("%s", input);
printf("%s", input);
return 0;
}
My goal is to be able to break that string into chars that i can search through to find whitespace and thus being able to isolate those words for example, if my input was "This is bad" i'd like the code to print out
This
is
bad
Edit:
I have modified my code to fit one of these answers but the problem i run into now is that it won't compile
int main()
{
char input[20];
printf("Please enter your words:\n");
size_t offset = 0;
do
{
scanf("%c", input + offset);
offset++;
}
while(offset < sizeof(input) && input[offset - 1] != '\n');
}
printf("%c", input[]);
return 0;
Problems:
1) scanf("%c", input); only set the first element of the array input.
2) printf("%c", input[1]); prints the second element of the array input, which has uninitialized data in it.
Solution:
Small state machine. No limit on string size like 20.
#include <ctype.h>
#include <stdio.h>
int main() {
int ch = fgetc(stdin);
while (ch != EOF) {
while (isspace(ch)) {
// If only 1 line of input allowed, then add
if (ch == '\n') return 0;;
ch = fgetc(stdin);
}
if (ch != EOF) {
do {
fputc(ch, stdout);
ch = fgetc(stdin);
} while (ch != EOF && !isspace(ch));
fputc('\n', stdout);
}
}
return 0;
}
scanf("%c", &input); does not do what you think it does.
First of all, %c scans only a single character: http://www.cplusplus.com/reference/cstdio/scanf/
Second, array's name is already a pointer to it's first element, so stating &input you make a pointer to a pointer, so instead of storing your character in array's first element you store it in pointer to the array which is a very bad thing.
If you really want to use scanf, I recommend a loop:
size_t offset = 0;
do
{
scanf("%c", input + offset);
offset++;
}
while(offset < sizeof(input) && input[offset - 1] != '\n');
Using scanf("%s", input") leaves you vulnerable to buffer overflow attacks if the word is longer than 20 characters http://en.wikipedia.org/wiki/Buffer_overflow
In my example I assumed, that you want to finish your word with a newline character.
EDIT: In scanf documentation is also a good example:
scanf("%19s", input);
It scans no more than 19 characters, which also prevent buffer overflow. But if you want to change input size, you have to change it two places.
You can use
char * strtok ( char * str, const char * delimiters );
to tokenize your string. If you have your input in input[] array and want to tokenize the string accoring to whitespace character, you can do the following :
char *ptr;
ptr = strtok(input, " ");
while(ptr != NULL) {
printf("%s\n", ptr);
ptr = strtok(NULL, " ");
}
Only the first call to strtok() requires the character array as input. Specifying NULL in the next calls means that it will operate on the same character array.
Your scanf only picks up the first character, input[1] contains random garbage. Use scanf("%19s", input) instead.

why my "gets" function can't really get a string?

My problem looks very simple and im so sorry for asking but what its wrong with this code?! why is just skipping the name part?!
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define nl printf("\n")
struct date{int day,month,year;};
struct student{long int id;char name[30];struct date birthday;};
int main()
{
struct student temp;
nl;nl;printf("ID no:");scanf("%ld",&temp.id);nl;
printf("Student name:");
gets(temp.name);
nl;nl;
printf("Student birthday year:19");scanf("%d",&temp.birthday.year);nl;
printf("Student birthday month");scanf("%d",&temp.birthday.month);nl;
printf("Student birthday day");scanf("%d",&temp.birthday.day);nl;
getch(); //for pause
return 0;
}
Is there anything wrong about gets function?! cause i don't want to use scanf("%s",) because of space thing...
This is because it reads the \n character left behind by scanf. Use
int ch;
while((ch = getchar()) != '\n' && ch != EOF);
to consume \n.
And better not to use gets as it fails in array bound check. Use fgets instead.
As said by haccks, you should not use gets(), but if you really want to use it in your code use gets() before the id no. ie after the struct student temp; line, and if you want to print it then simply puts(temp.name) .

Not able to break from while loop using getchar in C

I am new newbie, facing a basic problem, Not able to break while loop using getchar.Following code compiles successfuly but keeps displaying "Please enter NAME" only and keeps taking typed characters from KeyBoard but doesn;t break on typing enter for new line character :-(
#include<stdio.h>
typedef struct employee
{
char name[20];
int age;
char country[20];
}emp;
void getinfo(char *str, const char *param)
{
int i;
char ch;
if (strcmp(param,"NAME" ) == 0)
{
printf("\nPlease enter NAME \n");
}
else if(strcmp(param, "COUNTRY") ==0)
{
printf("\nPlease enter COUNTRY \n");
}
while((ch==getchar())!= '\n')
{
str[i] = ch;
i++;
}
str[i]= '\0';
}
int getage(int *age)
{
printf("\n Please enter Age \n");
scanf("%d",age);
}
int main(void)
{
emp e1;
getinfo(e1.name, "NAME");
getinfo(e1.country, "COUNTRY");
getage(&e1.age);
}
Please provide help.
The
while((ch==getchar())!= '\n')
should read
while((ch=getchar())!= '\n')
^
Otherwise, you're comparing the (uninitialized) value of ch to getchar(), instead of assigning the result of getchar() to ch.
while((ch==getchar())!= '\n')
That line is currently an undefined operation since ch isn't assigned anything yet. Let's assume ch==getchar() is false, false != '\n' is true, since anything nonzero is true, and '\n' is greater than zero.
I assume you want to change the == in ch==getchar() to a single =.
You have typed while((ch==getchar())!='\n')
This statement calls getchar() and compares to the garbage value of ch, and compares against '\n'
it will be usually true, so the while loop keeps on executing even though ch is assigned nothing
So, change it to while((ch=getchar())!='\n')

Resources