I have an assignment that requires me to make a code to basically have the user input 5 letters into an array. The five letters then have to be checked against themselves for duplicates and they have to be letters. I am the worst at doing this, i will say that now. The book i have is about pointless, and i can't seem to find much information regarding C, most of what i find is C++ and what not. I am not sure how i need to approach this assignment. I was thinking i need to do an array or 5 elements (obviously) but how would i be best to compare them. would a bunch of singular entries be best? if i do that, and i add the ch to the array, then i would need some if statement to say "if a = b then blah, else (how do i add this to the array?)" and to throw the wrench, if they do equal, how do i tell the user to try again?

i have the following code written to check the user input to make sure they are actual letters

#include "stdafx.h"


     int main(void)
{


    char ch ;

printf("Please enter a character.\n");

scanf("%c",&ch); 
getchar();



    if (
96 < ch && ch < 123 ||
64 < ch && ch < 91
        )
        printf ("This is a valid character.\n");

        else
        printf("This is not a valid character, please try again.\n");








return 0;

}

past this point, i have spent a month on it an i am finally saying help!!!

you can start by asking the user to enter 5 letters not only 1. To do so you can use a for loop and save it into an array of chars

Edited 2 Years Ago by Slavi

You could (loop to) take in all 5 char's into a C string buffer at 'one go' ... using fgets and a sufficently (extra) large buffer

Then validate the 5 chars using ... these next 3 steps

  1. make sure 5 and only 5 chars long ... use strlen, include <string.h>

  2. use isalpha ... need to include <ctype.h> to make sure all char's are alpha ... as you traverse the C string

  3. make a copy into another C string buffer and sort (could use a bubble sort) and then traverse that sorted copy to see if each next char is always different from the previous

Note: you could code an 'isValid' function to handle all this.

/* prototype of a function to validate a C string ... */

/* returns 0 if NOT valid, otherwise return 1 */
int isValid( cont char* testStr );

/* Note: you MUST define before using the above */

Note 2: Recall that a C string is really just an array of char's, with an added terminal '\0' char ... to 'flag' the end.

Edited 2 Years Ago by David W

everyone keep in mind, i know very little. i have read the book i got from the class a few times and understand what the uses are individually. but as to actually writing a code to make the functions preform as needed, im clueless. i have little to no desire to want to write code for the rest of my life lol.

David, your suggestion i tried to use it, but the problem is this. The way the assignment is, it requires the user to enter one letter at a time. Upon entry, i am to store it into the array ([5] wide) as well as scan each entry to see if a duplicate exists in the array. If there is, i have to ask the user to try again. If it is a unique char, then i am to move on to the next memory location and do it all over again.

My biggest problem with this is i keep trying to apply the process of writing basically subroutines like i did when i was writing programs for microcontrollers. you could name something, assign it a task, and call upon it in the program. i dont know if you can do it with this or not. for example, i tried to name "letters" and said "letters = ( the code from above)" and i have no idea if visual studios allows you to do this. also, every time i try to make a program, i keep getting a linker error that i have to make the program not incriment.

can you even do this and use a call to make this work where needed?

int letter;
        letter = (

96 < ch && ch < 123 ||
64 < ch && ch < 91 ) ;

That code will in fact work, but it isn't typical C idiom, and isn't quite what you seem to have in mind. Basically, what you are doing with this is evaluating a boolean value and assigning the result to the variable letter. It does not assign the code to the variable, just the value of the result. This isn't what you seem to have in mind.

What you are really asking for, in effect, is how to write a function in C. You have the right idea, sort of, but lack the syntax for how to do it.

In C, a function consists of a declaration, and a body. The declaration and body look like this:

<type> <name> (<parameters>)
{
    <body>
}

where <type> is the function's return type, <parameters> is a list of zero or more variable declarations, separated by commas, and <body> is the actual code. Note the curly braces around the code; that is the basic C syntax for a block of code, and is used in if() statements, for() loops, and while() loops as well. For example,

double sum_of_squares(double x, double y)
{
    double a, b;

    a = x * x;
    b = y * y;
    return a + b;
}

declares a function that takes two double values and retusn another double. For functions that don't return a value, there is a special type, void, which indicates that there is no return value.

So, for the case above, you would probably declare the function as

 int is_letter(char ch) 
 {
     return ((96 < ch && ch < 123) || (64 < ch && ch < 91));
 }

or in slightly more modern C

 bool is_letter(char ch) 
 {
     return ((96 < ch && ch < 123) || (64 < ch && ch < 91));
 }

(though you would need to #include the <stdbool.h> header for the bool type.)

You'll note that the main() part of the program looks a lot like this; that is because main() is in fact a function as well, though it is never a good idea to call it directly as the compiler treats it rather uniquely.

Note also that the compiler has to be able to know what a function's return type and parameter types are before it is used. In order to declare a function before is is implemented, you would write just the function's declaration followed by a semi-colon.

 bool is_letter(char ch);

This is called a function's prototype, and tells the compiler what it needs to know to allow you to call the function. You can even have a file full of nothing but function prototypes, called a header file, which can be inserted into a program's compiled code automatically with the #include pre-processor directive. That's is what the directives like

#include <stdio.h>
#include "myfunctions.h"

are really doing. These allow you to compile code that calls functions that are already compiled in another file. When you compile the program, the compiler also links your program with such library files to make your full program.

For simple code, there are also macros, but in C macros are quite limited; you are usually best off avoiding them, except for very, very simple things, or cases where you absolutely need to manipulate the code itself. Focus on functions rather than borrowing trouble with the pre-processor.

So, in your existing code, you could have:

#include <stdio.h>
#include <stdbool.h>

bool is_letter(char ch);

int main(void)
{
    char ch;

    printf("Please enter a character.\n");
    ch = getchar();

    if (is_letter(ch)) 
    {
        printf ("This is a valid character.\n");
    }
    else
    {
        printf("This is not a valid character, please try again.\n");
    }

    return 0;
}

 bool is_letter(char ch) 
 {
     return ((96 < ch && ch < 123) || (64 < ch && ch < 91));
 }

Note the way I've indented the code; that's important for making the code readable. While indent style is the subject of perrenial debate, everyone agrees that indentation of some sort is important.

As it happens, there already is a standard library function (well, actually it is usually a macro, but that's not the point) called isalpha() which does what you want. Its declaration is in the <ctype.h> header. So you could simply do this instead:

#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char ch;

    printf("Please enter a character.\n");
    ch = getchar(); 

    if (isalpha(ch)) 
    {
        printf ("This is a valid character.\n");
    }
    else
    {
        printf("This is not a valid character, please try again.\n");
    }

    return 0;
}

By the way, the "stdafx.h" header is not standard C; it is specfic to Visual Studio, and frankly, better off avoided.

Edited 2 Years Ago by Schol-R-LEA

BTW, what textbook are you using? It might help us understand why you are having so much trouble with it, and if it is as bad as you say, we'll know to steer others away from it.

Comments
forgot to mention, i am using VS 2010. which doesnt help me at all

C Primer Plus, Stephen Prata, 5th Edition, Sams, 2005

The book itself isnt "bad" persay, it just doesn't help me very much with these assignments and it is tough to locate information that pertains to what i am being asked to do. Most of what i am finding is based on one of two things. Either you are a programmer and the "lingo" is easy to some, but others just hear Chinese, or, it is so basic that it is no help at all.

I really do want to thank all of you for helping me on this. Tomorrow morning i will make another go at this. I just want to be able to turn something in and get a grade for this assignment. I am passing the class already oddly enough, but this assignment just is a little past me. I am not sure if i am trying to over complicate it or what (which i am sure is the reason).

FYI, this class is a "self taught" class. The teacher isn't really available to guide me much and when i ask questions i tend to get responses like "all you have to do is" or "just make a simple input program, scan it and if its valid, add it to the array." Everyone here has taught me more than he has all semester. :)

David, your suggestion i tried to use it, but the problem is this. The way the assignment is, it requires the user to enter one letter at a time. Upon entry, i am to store it into the array ([5] wide) as well as scan each entry to see if a duplicate exists in the array. If there is, i have to ask the user to try again. If it is a unique char, then i am to move on to the next memory location and do it all over again.

Ok ... so you can code a function ...

int alreadyExits( char testChr, const char* ary, int size )
{
   for( int i = 0; i < size; ++ i )
      if( ary[i] == testChr ) return 1;
   /* else if reach here ... */
   return 0;
}

And could use this ...

int takeInChr( const char* msg )
{
    char chr;
    printf( msg ); fflush( stdout );
    chr = getchar();
    if( chr != '\n' ) while( getchar() != '\n' ) ; /* flush stdin ... */
    return chr;
}

At top can have ...

/* ... */
#include <ctype.h> /* re. isalpha */
#define ARY_SIZE 5

Then in main ...

char ary[ARY_SIZE];
int size = 0;
printf( "You will now be asked to enter %d unique letters ...\n", ARY_SIZE );
while( size < ARY_SIZE )
{
   char c = takeInChr( "Enter a letter: " );
   if( isalpha( c ) )
   {
      if( !alreadyExist( c, ary, size ) )
      {
         ary[size] = c; /* Ok to append ... */
         ++size;
      }
      else
         printf( "The letter %c already exists.\n", c );
   }
   else
      printf( "%c is NOT valid input here.\n", c );  
}

Edited 2 Years Ago by David W

Comments
thank you for this, it started to point me in the right direction. then my head exploded when i was trying to adapt your code to my needs and after 25 errors, i gave up.

David, i am curious to know what the purpose of lines 11 and 12 were. the comment "ok to append" and the ++size are confusing me. the ++ size i am assuming to be an incrimentor (but i have never see one outside a loop before) and the ary[size] = c just doesnt make any sense to me. can you explain those please?

You are correct about ++ being the increment operator; it is commonly used in C code, but yes, it most often shows up in a for() loop.

The ary[size] = c is an assignment to a element of an array (a block of memory holding a linear collection of items of the same type), where size is an integer between zero and ARY_SIZE-1 (actually, it can be any integer, but a valid subscript is going to be in that range). ary is the name of the array, and [size] is the subscript of the array, that is, the number of the element in the array to access. So, if you have an array of five ints named foo, you would declare it as int foo[5];, so that foo[0] is the first integer in the array, foo[1] is the second, and so forth up to foo[4].

Edited 2 Years Ago by Schol-R-LEA

I figured that incrementer was incorrect in c. I know how the declaration of an array size and how the counter works (I am actually going for my electronics engineering degree and doing a c programming class is a requirement in my state). The actual elements of an array of 5 blocks is 0 through 4 (or n-1) ... Again, than you all for being patient with me.

I have to agree that writing good 'c' code can be somewhat unforgiving - even more so that c++ although abstractly speaking c++ has more paradigms which actually makes it more difficult.

Handing input alone from the command line can be difficult and scanf is fraught with danger, that most people advise rolling out your own using fgets().

The current king of cprogramming has to ... symbol clash... cprogramming.com.

And I always tend to consult their handy FAQ if I was to ever write any c code - which I hardly ever do now. I don't try to understand why they use fgets() over scanf, I just take it as gospel so I can get down to the nitty gritty bit, which is writing the algorithm itself to do the useful part of the program.

For you I can see how you can get somewhat confused using the integer characters for letters ch 93 < ch 123 and to the unitiated they seem like magic numbers picked at random.

Therefore I always endorse using a simple char array to do letter checks.

For example char letters[] = "abcdefghijklmnopqrstuvwxyz";

and then run a nested for loop on the input to check if it is good.

To make sure you input isn't duplicated I would suggest using a letter frequency counter. That way you can easily tell if a letter is duplicated. For instance, any letter count over 1 is clearly a duplicate.

The key here, is to use the a nested for loop, so that's one for loop inside the other with an if statement as a comparison.

DavidW has given you a good place to start at writing your letter frequency counter.

Edited 2 Years Ago by iamthwee

Comments
i like how you tried to explain it, it did clear stuff up. only problem is, it gave me more questions after and i went cross-eyed

I've a different way to solve your problem. I think why don't you specified input method for user, what allowed to user can type and can't type.

So you can refer to the code bellow:

    #include <stdio.h>
    #include <conio.h>

    char str[6];
    char *enter(){
        char c, i = 0;
        while(c != 13 || !i){
            c = getch();
            if(c == 8 && i > 0) printf("\b \b"),i--;
            if(c < 65 || c > 90 && c < 97 || c > 122 || i > 4) continue;
            str[i++] = c;
            printf("%c", c);
        }
        str[i] = 0;
        return str;
    }
    int main(){
        char *string = enter();
        printf("\n%s", string);
    }

Edited 2 Years Ago by Sinz_1

Comments
this would have been great, but i have no clue what your code was doing half the time and visual studios was giving me more errors than i cared to deal with.

Iamthewee, i actually wrote that program for another assignment where i had to validate the users input and make sure it was a letter. It was the easiest way i could think of was to validate the ASCII input within a certain range. Also, thank you for that link. I have it open right now an i am seeing just what all there is to it that i can use for information.

Blah, i see how much of a headache "C" is now. Everyone has a different style, and I am sure each compiler allows different things as well. I wish they would just allow me to take something that is a lot more cut and paste than this. lol.

I am throwing in the towel. I can not seem to grasp what direction i need to take this. basically, what i need it to do is this:

Enter first letter (scan to see if letter, if not tell user to try again)

Enter second letter (scan again as above, see if letter 2 = letter 1. if yes, try again)

Enter third (scan above again)

Enter fourth (same again)

Enter fifth (last time)

if all goes well, print the array[5]

for the life of me, i can not get this to solidify in my brain. my biggest problem is all the new stuff that i dont know what it is (like the "isalpha" from above or the new libraries (forgive me for not spelling everything right and proff reading, but my brain and eyes hurt right now). i know this above is no simple task ... but it really should not be this tough to do. for the life of me, this is beyond me. thank you all again, you all tried to help me. i will admit that.

Enter first letter (scan to see if letter, if not tell user to try again)

Enter second letter (scan again as above, see if letter 2 = letter 1. if yes, try again)

Enter third (scan above again)

Enter fourth (same again)

Enter fifth (last time

And ... what do think this does (if ARY_SIZE was 5) ?
(copy/pasted from above, with a few changes in comments)

char ary[ARY_SIZE];
int size = 0;
printf( "You will now be asked to enter %d unique letters ...\n", ARY_SIZE );
while( size < ARY_SIZE )
{
   char c = takeInChr( "Enter a letter: " );
   if( isalpha( c ) ) /* 'scan' to see if letter */
   {
      if( !alreadyExist( c, ary, size ) )
      {
         ary[size] = c; /* Ok, accept (i.e.append) */
         ++size; /* get ready for next entry */
      }
      else
         printf( "The letter %c already exists, try again.\n", c );
   }
   else
      printf( "%c is NOT valid ... try again.\n", c );  
}

Edited 2 Years Ago by David W

I would go back to the very basics and write a flow chart. I would also forget using functions as I can tell you're very new to this.

Very new is an under statement. This is something that I would need someone to be next to me to explain the process to me. Having to learn this stuff on my own basically (just reading a book) is making this extremely unappealing. I don't mind programming micro controllers at all, but this is foreign. Also, like I said earlier, I think using visual studio as a compiler is causing me more headache because it is full of bugs.

There are plenty of things about VS that have caused me headhaches before, to be sure, but most of them weren't bugs per se. What problemas are you having?

If you are having as many problems with the IDE as you say you are (and I have no reason to doubt it), you might consider working on the code in a different environment and then copying it to Visual Studio for the version you turn in to the instructor. You can do the editing in an text editor (even Notepad would be sufficient, if rather primitive; Notepad++ is a good starting place, while many coders swear by Sublime Text, and I personally use GNU Emacs quite a bit, but I'm old-fshioned that way), and use a command-line compiler like the MS C/C++ compiler that comes with Visual Studio (the shell command for it cl.exe) or the MinGW port of GCC.

Alternatively, you could get a suitable IDE, such as Pelles C or Code::Blocks, and use that.

As long as you stick to the Standard C language and avoid any extensions, you should be OK when you move it back to Visual Studio. Oh, and make sure to use the C settings and the .c extension on the source files, so that the comipler or IDE knows it should be compiled as C code and not C++.

Edited 2 Years Ago by Schol-R-LEA

You are making it much harder than it is ...

printf( ...) is a function
int main( ... ) is a function

Functions are really easy ...

(once you 'see' that ...
functions are just named blocks of code that can accept values passed in ... and then execute that block of code when ever called by the name you give that function...)

Fuctions help you 'see' the logic flow readily

int size = takeInFileData( fname, ary, maxArySize );
if( size != -1 ) // -1 was value returned if error with file open
{
    findAverageAndReport( ary, size );
}
else
   //print error message re file open problem

Edited 2 Years Ago by David W

This article has been dead for over six months. Start a new discussion instead.