Thread: character inputs and linked lists

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    4

    character inputs and linked lists

    hi, i really need help please.
    this code is using scanf with linked lists and the problem im mainly having is that if the input is more than one word eg 'hello world', it doesnt input the two words inside the array. its supposed to be reading from standard input and the 1st letter of each node is printed out. and if its a vowel, it prints out a * after the letter. heres an example of input output.

    input:
    all
    people are
    able
    to
    breathe

    output:
    a*pa*tb

    its skipping the whitespace. ive tried using getchar, but i dont know how to properly copy the characters individually into the array. i also want to keep the code as simple as possible.

    Code:
    #include<stdlib.h>
    #include<stdio.h>
    #include <string.h>
    
    typedef struct Node {
       char string;
       struct Node * next;
    }Node;
    
    int main()
    {
    	Node * curr, * head = NULL, * previous = NULL;
    	char line[100];
    	char *linep;
    	char ch;
    
    	while((scanf("%s", line)) != EOF)
    	{
    		linep = strdup(line);
    		curr = (Node *)malloc(sizeof(Node));
    		curr->string = linep[0];
    
    		if(head == NULL)
    		{
    			head = curr;
    			previous = curr;
    		}
    		else
    		previous->next  = curr;
    		previous = curr;
    	}
    
    	curr = head;
    	while(curr)
    	{
    		ch = curr->string;
    		printf("%c", ch);
    		if(ch == 'a' || ch == 'A')
    		printf("*");
    		if(ch == 'e' || ch == 'E')
    		printf("*");
    		if(ch == 'i' || ch == 'I')
    		printf("*");
    		if(ch == 'o' || ch == 'O')
    		printf("*");
    		if(ch == 'u' || ch == 'U')
    		printf("*");
    
    		curr = curr->next;
    	}
    	return(0);
    }
    cheers

  2. #2
    Beginner leiming's Avatar
    Join Date
    Jan 2008
    Location
    Fujian, China
    Posts
    25
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    typedef struct Node {
       char string;
       struct Node * next;
    }Node;
    
    int main()
    {
    	Node * curr, * head = NULL, * previous = NULL;
    	char line[100];
    	char *linep;
    	char ch;
    
    	while((scanf("&#37;[^\n]", line)) == 1)
    	{
    		linep = strdup(line);
    		curr = (Node *)malloc(sizeof(Node));
    		curr->string = linep[0];
    
    		if(head == NULL)
    		{
    			head = curr;
    			previous = curr;
    		}
    		else
    		previous->next  = curr;
    		previous = curr;
    		stdin->_cnt = 0;
    	}
    
    	curr->next = NULL;
    	curr = head;
    	while(curr)
    	{
    		ch = curr->string;
    		printf("%c", ch);
    		if(ch == 'a' || ch == 'A')
    		printf("*");
    		if(ch == 'e' || ch == 'E')
    		printf("*");
    		if(ch == 'i' || ch == 'I')
    		printf("*");
    		if(ch == 'o' || ch == 'O')
    		printf("*");
    		if(ch == 'u' || ch == 'U')
    		printf("*");
    
    		curr = curr->next;
    	}
    	return(0);
    }

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    better yet use fgets to read full line, and do not access members of stdin due to portability problems
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User
    Join Date
    May 2008
    Posts
    4
    thanks for your replies, but i have tried leiming's modification, but it doesnt compile in unix gcc (because of the _cnt). and i have no idea how to use fgets

    ive thought about this tho. but the problem with this code is that if i enter 'asdf' that stores in the variable c. how do i get ONLY the first character from the input? the getchar seems the easiest method for me (i think), but i dont know how to only get the first character and ignore the rest.

    cheers

    Code:
    int main()
    {
    	Node * curr, * head = NULL, * previous = NULL;
    	char line[100];
    	char *linep;
    	char ch;
            char c;
    
    	while((c=getchar()) != EOF)
    	{
    		curr = (Node *)malloc(sizeof(Node));
    		curr->string = c;
    
    		if(head == NULL)
    		{
    			head = curr;
    			previous = curr;
    		}
    		else
    		previous->next  = curr;
    		previous = curr;
    	}

  5. #5
    Beginner leiming's Avatar
    Join Date
    Jan 2008
    Location
    Fujian, China
    Posts
    25
    I'm sorry that I find my way to flush input buffer is seriously wrong.

    try this?

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    typedef struct Node {
       char string;
       struct Node * next;
    }Node;
    
    int main()
    {
    	Node * curr, * head = NULL, * previous = NULL;
    	char line[100];
    	char *linep;
    	char ch;
    	char useless;
    
    	while((scanf("&#37;[^\n]%c", line, &useless)) >= 2) /* %c to "eat" the '\n' */
    	{
    		linep = strdup(line); /* by the way, I can't make sure if it's necessary to "free(linep)" ? */
    		curr = (Node *)malloc(sizeof(Node));
    		curr->string = linep[0];
    		/* free(linep); */
    		if(head == NULL)
    		{
    			head = curr;
    			previous = curr;
    		}
    		else
    		previous->next  = curr;
    		previous = curr;
    	}
    
    	curr->next = NULL;
    	curr = head;
    	while(curr)
    	{
    		ch = curr->string;
    		printf("%c", ch);
    		if(ch == 'a' || ch == 'A')
    		printf("*");
    		if(ch == 'e' || ch == 'E')
    		printf("*");
    		if(ch == 'i' || ch == 'I')
    		printf("*");
    		if(ch == 'o' || ch == 'O')
    		printf("*");
    		if(ch == 'u' || ch == 'U')
    		printf("*");
    
    		curr = curr->next;
    	}
    	return(0);
    }
    Last edited by leiming; 05-25-2008 at 06:18 AM.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Use
    while ( fgets( line, sizeof line, stdin ) != NULL )

    and this whole "flush the buffer" thing goes away. Dealing with a newline in a char array is far simpler than any kind of "flush input" hack you can come up with.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    /* &#37;c to "eat" the '\n' */
    to eat input use * in scanf format
    for example

    %*c - and you do not need any useless variables

    PS. I'm not talking about this very case - Salem's solution is enough
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    Beginner leiming's Avatar
    Join Date
    Jan 2008
    Location
    Fujian, China
    Posts
    25
    Quote Originally Posted by vart View Post
    to eat input use * in scanf format
    for example

    &#37;*c - and you do not need any useless variables

    PS. I'm not talking about this very case - Salem's solution is enough
    I find a problem with * in scanf format.
    BCC thinks this is a successfully read one while GCC not.

    Quote Originally Posted by Salem View Post
    Use
    while ( fgets( line, sizeof line, stdin ) != NULL )

    and this whole "flush the buffer" thing goes away. Dealing with a newline in a char array is far simpler than any kind of "flush input" hack you can come up with.
    Excuse me, why did I find fgets returns an array {'\n', '\0'} instead of NULL when an empty line is got?
    Is there anything wrong with my operation?
    Thanks.
    Last edited by leiming; 05-25-2008 at 06:03 PM.

  9. #9
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    >Excuse me, why did I find fgets returns an array {'\n', '\0'} instead of NULL when an empty line is got?

    Leiming, thats how the fgets has been implemented. It reads the whole content of the input buffer including the '\n' char, which the scanf does leave them in the input buffer, which then causes lots of problem in the future, when using any operation which needs to access-the standard input. If your using fgets then its obvious that you need to eliminate the '\n' char from the vector by using the strchar and replacing it with the '\0'.

    Pleas read one of our FAQ about, how to read string from the user or something. Which explains the complete usage of fgets and internal working mechanisms.

    ssharish

  10. #10
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    BCC thinks this is a successfully read one while GCC not.
    get rid of bcc?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  11. #11
    Beginner leiming's Avatar
    Join Date
    Jan 2008
    Location
    Fujian, China
    Posts
    25
    >>ssharish2005

    Thanks for your explaining.

    But I knew this before. Maybe I didn't express myself clearly. (Sorry to not learn English well)
    I mean, an empty line couldn't end the loop if using Salem's code.
    Or I didn't got it how people usually do to show that the input is over.

    By the way, I have tried to use his code again just now and found that pressing "Ctrl + Z" and then pressing "Enter" could make fgets return NULL.

    LeiMing

    by the way, I writes no code in this post but when I quotes your post then posts it it forces me to use code tag. How to deal with it correctly?

  12. #12
    Registered User
    Join Date
    May 2008
    Posts
    4
    thx for all your replies. i was just wondering, is there any way to implement this with getchar() and getting only the first letter of the input like my previous post? i just feel that this exercise is better to use with getchar() != EOF. but when i use getchar() it returns the whole input. i only want the first letter.

    cheers

  13. #13
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Quote Originally Posted by zomg View Post
    thx for all your replies. i was just wondering, is there any way to implement this with getchar() and getting only the first letter of the input like my previous post? i just feel that this exercise is better to use with getchar() != EOF. but when i use getchar() it returns the whole input. i only want the first letter.

    cheers
    Zomg, its not an efficient way of doing this with the getchar. That takes too much code and perhaps you will have to read stuff char by char and then append it the string. See the following code for the fgets usage.

    Code:
    #include <stdio.h>
    int main()
    {
        char cont[25];
        char *ptr;
        
        while( fgets( cont, sizeof cont, stdin) != NULL )
        {
               if( ( ptr = strchr( cont, '\n' ) ) != NULL )
                   *ptr = '\0';
               printf( cont ); 
               
               /* Here, fill you structure data members
                  by the string which is read above. Use
                  strcpy function to copy it onto structure
                  memeber */
        }
        return 0;
    }
    NOTE: You will have press Clt + Z. To stop reading values from user.

    ssharish

  14. #14
    Registered User
    Join Date
    May 2008
    Posts
    4
    awsome. there is just one more thing i would like to ask. well atm my uni website is actually testing the code, and its not passing every test. i think its actually of one thing: how do i make it do nothing, if there is no input. eg if i just press enter, how do i make it do nothing, instead of making it allocate a element with a space? atm its actually placing a space inside the element and i think its meant to do nothing.

    cheers

  15. #15
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Quote Originally Posted by zomg View Post
    awsome. there is just one more thing i would like to ask. well atm my uni website is actually testing the code, and its not passing every test. i think its actually of one thing: how do i make it do nothing, if there is no input. eg if i just press enter, how do i make it do nothing, instead of making it allocate a element with a space? atm its actually placing a space inside the element and i think its meant to do nothing.

    cheers
    Ok, what you need to do is to check the first element in the string and see if its a '\n' char. If it, then you know that the user had has entered nothing. From there on, you either exit the code or come out of the loop and so something else. Few points to hightlight

    1. Check the first element in the string
    2. If that element is '\n'
    3. Then user entered nothing

    Hope you get that part.

    ssharish

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Concatenating in linked list
    By drater in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 11:10 PM
  2. Linked lists...need help with a little something
    By Todd88 in forum C++ Programming
    Replies: 2
    Last Post: 04-28-2008, 08:05 PM
  3. Anyone good with linked list.....I am not....
    By chadsxe in forum C++ Programming
    Replies: 11
    Last Post: 11-10-2005, 02:48 PM
  4. Linked List help
    By KirbyMorph in forum C Programming
    Replies: 3
    Last Post: 02-09-2003, 10:11 AM
  5. Linked List Problem
    By animeaholic in forum C Programming
    Replies: 1
    Last Post: 12-09-2002, 06:36 PM