What do I do now? - c

It may be really simple, but I don't really know what to do now.
I just recently got in programming and I thought I should start by learning C, I know a few stuff here and there but I just recently got into this problem and I can't figure it out.
Im trying to make a register/login system that stores the credentials into strings using scanf(), I don't really know how to get the login part to work. Do I need to create more strings and store the input there? Or how can I compare the user's input to the value in the strings?
My code is currently looking like this:
#include<stdlib.h>
#include<time.h>
char user[30] = "";
char password[30] = "";
char yn[30] = "";
char Y[1] = "Y";
char N[1] = "N";
int main() {
printf("Register\n");
printf("The User or Password can't be longer than 30 characters\n");
printf("User: \n");
scanf("%s", &user);
if (user == NULL)
printf("User can't be empty\n");
else
printf("Password: \n");
scanf(" %s", &password);
if (password == NULL)
printf("Password can't be empty\n");
printf("User saved as: \n");
printf("%s\n", &user);
printf("Password saved as: \n");
printf("%s\n", &password);
printf("Is this correct?\n");
printf("Y/N\n");
scanf("%s", yn);
if(yn == Y){
printf("\e[1;1H\e[2J");
}
if(yn == N){
printf("Restarting...");
}
printf("Login\n");
printf("User: \n");
}
It all works well (except I can't figure out how to clear the console before asking to log in, this wont work printf("\e[1;1H\e[2J");), I even managed to print out the user's input to the console for him to make sure its correct and I made a (Y/N) thingy. Can someone help me please?

You can create functions instead of having them all in the main.
Create a register function that saves the data and a login function that asks for data as parameters and the call it in the main.
Maybe you can create a simple menu.

When you first learn a language, you discover certain patterns of how it can be used. Some of your problems come from overusing patterns where they don't make sense.
For example, you know you can compare two variables with == but that compares values, and in some cases you are comparing references as if they were values. References are memory addresses, and if you have two letters Y in RAM then they are distinct, having two different references, even if their value is the same.
Since a lot of your processing uses strings, read through the functions available when you #include <string.h> You will hear a lot about how some of these are unsafe to use; for now I recommend skipping safety arguments as they make more sense after you know how to call the functions.
For example
if (yn == Y) {
is not going to give you the desired result, but
if ( strcmp( toupper( yn[0] ), "Y" ) == 0 ) {
will give you the desired result. As in most cases, there are other ways to write the same logic; but, for those who want to offer more efficient ways of checking yn, this is an example designed to show off string functions.
Strings in C are not single values. They are an address (sometimes called a reference) to a pieced of memory, which if you keep reading char-by-char should eventually end in a NULL character, a char containing the number 0. This means that they cannot be compared directly as in yn == Y because you are comparing two memory addresses, not two sequences of chars.
The above example is a simplification of what strings can be. It's a good enough of a definition for a beginner; but, over time you will find that this definition is very old, and has been revised over time. The problem is that a char can only hold 8 bits, so when more than 256 distinct values were needed, a solution was created to hold more values.
The first solution was to use a "wide character" called a wchar, which has the type of wchar_t. This is like a char, but it holds 16 bits. This started the whole "char" vs "wchar_t" problems. For now you can ignore them, but be aware that if you ever work with wchar_t you need wchar compatible functions.
The second solution was to introduced Unicode, which provides enough characters that nearly every language can be written within Unicode, even most dead languages, emojis, upside down text, etc. Unicode doesn't have a single way of representing its characters, but there are two popular ones for the beginning programmer. UTF-32, which used 32 bytes for each character, is popular because it is easy to program. UTF-8 is popular because it is the effective "correct choice" for the Internet due to it extending ASCII and being the format of the Internet.
Once you get familiar with strings, you might want to spend some quality time with UTF-8.
Good luck.

Related

'comparison between pointer and integer' error for Phone Directory program

So I'm pretty new too C, and programming. I'm learning little by little. A friend of mine gave me a good idea for a first project. The goal is too allow the user too select a department (Phone Directory for a Casino), and once that department has been selected, it will show all the numbers for that department.
Eventually I want too add more too this, but for now, I'm going too keep it simple.
#include <stdio.h>
main()
{
printf("Please Select Department [Security, Food & Beverage, Hotel]\n");
char str[20];
gets(str);
if (gets(str) == 8)
{
printf("You have selected Security\n");
printf("218-760-1122, 218-760-5564\n");
}
else if (gets(str) == 5)
{
printf("You have Selected Hotel\n");
printf("218-443-9810");
}
else if (gets(str) == 15)
{
printf("You have selected Security\n");
printf("218-550-9818, 218-443-1231\n");
}
return 0;
}
The problem with this program is when I compile and build the program, it prints the "selection" part of the script, where get(str) is used. After I select which one I would like too use, it goes blank, and nothing is displayed, but the script itself is still running.
I'm really new too this, and I'm assuming its something too do with how I'm determining which department is selected, in the if/else statements. I cant seem too figure out what I'm doing wrong. I've tried different solutions, usually getting different results, the closest being by adding a semi-colon too the last line of the else if statement, which runs the script, skips the first two else statements, and prints the security code.
3 warnings pop up for lines 10, 16, and 22
warning: comparison between pointer and integer [enabled by default]
This is a learning experience for me, and I would appreciate any help that can be offered.
So, the first and most important error is already in the comments, but repeating it here for completeness:
Do not use gets()! It is broken and therefore removed from the current C standard. With gets(), you have no control over how much input is actually read, so any buffer can overflow (and attackers will use that). The replacement is fgets(), which has a size argument.
Note the same holds for things like scanf("%s", ...). If you ever need to use a conversion to a string with the scanf family of functions, make sure to read the documentation, it tells you how to use a field width.
Back to your code, assuming you use fgets() like you should:
char str[20];
fgets(str, 20, stdin);
if (fgets(str, 20, stdin) == 8)
{
You have two errors here:
You call fgets() twice. Each call will attempt to read a line of input and store it in str. That's not what you want.
fgets() doesn't return the length but a pointer to str if it was successfull. If it failed, it returns NULL
So, the code should start like this:
char str[256];
if (!fgets(str, 256, stdin))
{
fputs("Error reading input.", stderr);
return 1;
}
Only after that error check, you should examine the contents of str, ie, what the user actually entered.
Note I also increased buffer size. People might enter longer lines by accident and there's really no need to be that tight with bytes nowadays.
Finally, just checking the length probably isn't a good idea. Instead, include string.h and use the strcmp() function.

Identyfying prefix in the same string as a suffix

Eg-
maabcma is valid because it contains ma as a proper prefix as well as a proper suffix.
panaba is not.
How do I find out if a word is valid or not as above in C language?
I'm not very good at string operations. So, please help me out with a pseudocode.
Thanks in advance.
I'm completely lost. T=number of test cases.
EDIT: New code. My best code so far-
#include<stdio.h>
#include<string.h>
void main()
{
int i,T,flag=0;
int j,k,len=0;
char W[10],X[10];
scanf("%d",&T);
for(i=0;i<T;i++)
{
scanf("%s",W);
for(len=0;W[len]!='\0';len++)
X[len]=W[len];
X[len]='\0';
for(j=len-1;j>=0;j--)
for(k=0;k<len;k++)
{
if(X[k]!=W[j])
flag=0;
else if((j-k)==(len-1))
flag==1;
}
if (flag == 1)
printf("NICE\n");
else
printf("NOT\n");
}
}
Still not getting the proper results. Where am I going wrong?
The thing is you are only setting the value of flag if a match exists, otherwise you must set it to 0. because see, if I have:
pammbap
my prefix is pam and suffix is bap.
According to the final for loop,
p and a match so flag is set to 1.
but when it comes to b and m it does not become zero. Hence, it returns true.
First, void is not a valid return type for main, unless you are developing for Plan 9.
Second, you should get into the habit of checking the return value of scanf() and all input functions in general. You can't rely on the value of T if the user does not input a number, because T is uninitialised. On that same note, you shouldn't use scanf with an unbounded %s scan operation. If the user enters 20 characters, this isn't going to fit into the ten character buffer that you have. An alternative approach is to use fgets to get a whole line of text at once, or, to use a bounded scan operation. If your array fits 10 characters (including the null terminator) then you can use scanf("%9s", W).
Third, single-character variable names are often very hard to understand. Instead of W, use word, instead of T, use testCount or something similar. This means that someone looking at your code for the first time can more easily work out what each variable is used for.
Most importantly, think about the process in your head, and maybe jot it down on paper. How would you solve this problem yourself? As an example, starting with n = 1,
Take the first n characters from the string.
Compare it to the last n characters from the string
Do they match?
If yes, print out the first n characters as the suffix and stop processing.
If no, increment n and try again. Try until n is in the middle of the string.
There are a few other things to think about as well, do you want the biggest match? For example, in the input string ababcdabab, the prefix ab is also the suffix, but the same can be said about abab. In this case, you don't want to stop processing, you want to keep going even if you find a prefix, so, you should just store the length of the largest prefix that is also the suffix.
Second-most-importantly, running into hurdles like this is incredibly common when learning C, so don't let this put a dampener on your enthusiasm, just keep trying!

C programming: IF statements

I need help on a problem on C programming. I was wondering if there is a way to have a user input a word to the console and it would display whatever you program it to. Heres a example of what I want to do
int Choice;
int Energy = 100;
printf ("Type 2817!\n");
scanf ("%s", &Choice);
if(Choice == 2817)
{
printf ("You have started the game\n\n\n\n\n\n\n\n\n\n\n");
}
else if(Choice == "Energy") //This isnt working in my compiler.
//Apparently the == sign is the underlined error
{
printf("%d", Energy);
}
So far I can only type numbers but I want to be able to type words and be able to use a command. SO basically I want to be able to type "Energy" and it will show the amount of energy you have (printf ("%d", Energy)
Please help,
Thank you for reading.
You have enter wrong datatype when comparing the choice (int type) with a string text. In C/C++ unlike dynamic programming language, you cannot compare int with strings without properly converting either of them. You use strcpy for comparing string and == for comparing int.
Then your programming will run.
I'm not sure what your program is trying to do, but let me concentrate on the few obviously incorrect lines.
First, in
int Choice;
scanf ("%s", &Choice);
you have the wrong type for Choice: it is "int" whereas it should be a static array of char (let's say char Choice[32]). In this case you also have to remove the "&" before "Choice" in the scant, so that the code becomes:
char Choice[32];
scanf ("%s", Choice);
Moreover, in
else if(Choice == "Energy") //This isnt working in my compiler.
you are trying to compare two strings with the operator "==". This does not work in C. You should use the function "strcmp" the following way:
#include<string.h>
[...]
else if(strcmp(Choice, "Energy")==0)
You'd even better use the following to prevent any buffer overflow
else if(strncmp(Choice, "Energy", 32)==0)
(replace 32 with the maximum number of elements in Choice)
Edit Note that you should change the first comparison too from
if(Choice == 2817)
to
if(strncmp(Choice, "2817", 32))
because Choice is not an int anymore...
The best way to approach this problem would to be to make Choice a string, then compare it to string values, or extract data from the string (for example with atoi) and assign it to other variables. C is a statically typed programming language, an int cannot become (or be compared to) a string because they are not of the same type. If you want arbitrary data from the user, the best way to approach that problem is probably to use a string. :-)
Read your input as array of chars
example
char bleh[250];
scanf ("%s", bleh);//or scanf ("%s", &bleh[0]);
and then use strcmp command to compare two arrays
strcmp(&bleh[0], "blabla"); //function will return 0 if two arrays match
hope this helps
"String" is const char *, you cannot compare using == in C++. You need to use strcmp to compare string.
strcmp returns zero if strings are same.
Few mistakes in the code.
use strcmp() to compare string.
Declare int Choice; to char Choice[50]
Remove & while reading string in scanf()
Comparing with if(Choice == 2817) is not correct. use if(strcmp(Choice , "2817") == 0)

Asking for a name and returning the length of the name in C

I've been struggling with this code for quite some time now.
This is my first time posting here. I am new to C, and I feel that I almost got it.
I have to ask for your name, middle initial, and last name. Then I greet you and tell you the length of your name. Sounds simple enough. I have the following code, I have to use the header file as it is here and that makes things worse. Any help would be greatly appreciated, I feel that I already applied all my knowledge to it and still can't get it to work.
This is my header file:
#ifndef NAME_H_
#define NAME_H_
struct name{
char first[20];
char middle;
char last[20];
};
#endif
and this is my .c file:
#include "name.h"
#include <stdio.h>
#define nl printf("\n");
int strlen(char*s);
char first;
char middle;
char last;
main()
{
printf("enter your first name : ");
scanf("%c", &first);
printf("\n enter your middle initial name : ");
scanf("%c", &middle);
printf("\n enter your last name: ");
scanf("%c", &last);
printf("\n\n Hello %c",first, " %c" ,middle, " %c", last);
printf("\n The String returned the following length: ",strlen);
}
I have t use printf and scanf, then store the name components a name "structure" imported from name.h and lastly use int strlen(char *s); to calculate it.
I get this output with the weird indentation and everything:
enter your first name : Joe
enter your middle initial name :
enter your last name:
Hello J
The String returned the following length: [-my user id]$
Thanks!
Several things about this are not quite right.
First, you shouldn't be declaring strlen yourself. It's a standard C library function, which means you should include the appropriate header. In this case,
#include <string.h>
Second, you're storing the input in variables of type char. Those are literally what they say: they store a single character. So unless you're only allowing people to have single-character names, you need a bit more than that. This sort of string input problem is actually rather tricky in C, since you have to do explicit memory management and don't know how much data the user is going to send you in advance. One of the simpler things is to just use a large buffer and truncate, but for a more complex program you'd want to do error handling and possibly dynamically resize the buffer. But for starters:
char first[1024];
char middle[1024];
char last[1024];
will at least get you started. Your struct name has some of this, but you're not currently using it (and the sizes are pretty small).
Next, scanf is a tricky way to get input strings. scanf of a %s pattern will happily read more than 1024 characters and write over the end of the buffer and destroy your program. This is why C programmers usually read input data using fgets instead, since then you can more easily say how big of a buffer you're willing to read:
fgets(first, sizeof(first), stdin);
Be aware that if the user enters more than 1023 characters, it will read the first 1023 characters and then leave the rest there, where you'll end up reading it as part of the middle name. String handling in C is complex! C is not good at this sort of thing; that's why people tend to use Perl or similar languages for this sort of interactive string handling where you don't know sizes in advance. In C, you have to pursue a strategy like repeatedly calling fgets until you get a newline at the end of the result and then deciding whether to dynamically resize your data structure or throw an error. Alternately, you can use scanf with %1023s but you need to qualify the format to specify the maximum length. The syntax is a bit weird and tricky; fgets is simpler when you're reading character strings.
As mentioned in the other answer, strlen is a function that you need to call on a char * variable (or char array) to get the length of the string it holds. You probably want to call it on first, middle, and last and add them together.
Finally, in your last printf, you have to pass one format and then all of the arguments for that format. You want something more like:
printf("\n\n Hello %s %s %s", first, middle, last);
(once you fix the type of those variables).
This is a lot of random detail. I hope it helps some. The important brief takeaway is that a string in C is a sequence of char ending in a char with a value of 0, and all C data structures have to be sized in advance (either statically or dynamically with malloc). C furthermore has no bounds checking, so it's completely up to you to ensure that you only read as much data as you created space for.
use
strlen(first)
to get the length of variable first ..similarly for other varibles... To get the cumulative length use
printf("\n Length: ",strlen(first)+strlen(middle)+strlen(last));

It is compiling but crashes everytime

I'm brand new to programming..im just trying to make my own program to find the volume and surface area of spheres and cylinders. I cant figure out why this program keeps crashing before it will get to the rest of the code. I'm guessing the char* might be wrong but i cant see why it would be.
int main()
{
char* solid;
char* unit;
printf("Welcome to the Center of Spheres and Cylinders!\n");
printf("Would you like to look at a Sphere or a Cylinder?: ");
scanf("%s", solid);
if(solid == "Cylinder" || solid == "cylinder")
{
printf("You chose to look at a Cylinder.\n");
else if(solid == "Sphere" || solid == "sphere")
{
printf("You chose to look at a Sphere.\n");
it crashes just after I input for scanf...when i type in either cylinder or sphere it crashes. Thank you for the help
solid is a character pointer, it is not pointing to any allocated memory location which is causing your program crash when you try to read data into it with scanf() ( and which is why it crashes right after that call as you observe).
After you declare
char *solid;
you should malloc() a certain amount of storage for it to point to. Alternatively you could have declared an array named solid
char solid[100];
Note that the crash is actually a good thing in that it is helpful to show there's a problem with an errand pointer. This may not always happen unfortunately depending on where a pointer in memory is pointing too.
The problem is with the line
if(solid == "Cylinder" || solid == "cylinder")
U cannot compare strings like that in C. Instead use strcmp library function available in C.
The code should be something like below
if( (strcmp(solid,"Cylinder")==0) || (strcmp(solid,"cylinder")==0) )
Hope this helps.
char* solid; creates a character pointer that points to an arbitrary location (at least for automatic variables, which is what you have in your code). Then, when you try to sccanf into that location, you're invoking undefined behaviour because there is no valid backing storage.
Something like char solid[100]; would create the backing storage, solving that immediate problem, since it allocates space for the characters to be stored. However, there are at least two other problems with your code.
The first is that you don't compare strings in C with ==, that merely compares the pointers, not the content behind the pointers. To compare the content, C provides a strcmp function so, rather than:
if (solid == "something")
you should have:
if (strcmp (solid, "something") == 0)
Some implementations may also provide stricmp which ignores case so you don't have to do:
if ((strcmp (solid, "something") == 0) || (strcmp (solid, "Something") == 0))
instead going with:
if (stricmp (solid, "something") == 0)
which will allow any characters to be upper or lowercase, such as SomeThing.
However, that's not standard C so it may not be available everywhere.
Your other major problem lies with scanf("%s"). Using an unbounded string here is unsafe as you're subject to buffer overflows if the user enters more than you expect. For example, if you use the afore-mentioned char solid[100] and the user enters five hundred characters, it's likely to trash your stack and cause yet another crash.
If you want a truly robust user input function, have a look at this one. It has overflow protection and throws away the rest of the line if necessary so that subsequent inputs are not affected.
Your program has several "flaws", as pointed out by the others:
The "star" denotes a pointer. A pointer must point to a location in memory, which can be done via malloc(), pointer assignment/manipulation, or explicit bit addresses. For more information on pointers, you can read this: http://pw1.netcom.com/~tjensen/ptr/pointers.htm (But seriously, pointers? You've mentioned you're a beginner in programming; pointers are an advanced concept not only in C, but in computer science as well. Anyways, do not think too much about them at the moment.)
String comparison in C is not done by the simple equality operator, but via bit comparison (which is automagically done by the library). The equality operator (==) compares only primitive types (int, char, etc) but not user-defined types or arrays (a string is a character array). You have to use strcmp() (or strncmp() to compare the first n bytes from an optional offset). You can search Google for the documentation of strcmp() and strncmp() for more information.
Keeping these concepts in mind, your program will be like this:
#include <string.h> /**Contains string manipulation functions; very important **/
#include <ctype.h> /**Contains tolower() **/
int main()
{
char* solid;
char* unit;
printf("Welcome to the Center of Spheres and Cylinders!\n");
printf("Would you like to look at a Sphere or a Cylinder?: ");
scanf("%s", solid);
if(strcmp(tolower(solid), 'cylinder') == 0)
{
printf("You chose to look at a Cylinder.\n");
else if(strcmp(tolower(solid), 'sphere') == 0)
{
printf("You chose to look at a Sphere.\n");
}
/** Other code here **/
return 0;
}
As you might have guessed, tolower() turns a string to lowercase. And additional FYI, an array is a pointer, so the justification in using the "star" notation for storing your input from scanf.

Resources