Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a little problem with a C-programm, I wrote. It should be like "you go in a room.. is there a wall? no? then move on.. is there a wall? yes? then turn around" and so on. I am stucked, I go in the room and turn around but do not know how to go further.
#include <stdio.h>
void main()
{
char answer[2];
answer[0] = "Y";
answer[1] = "N";
do
{
printf("Move!\n");
printf("Is there a wall?\n");
scanf("%s",answer);
}
while (answer[0] != 'Y' );
printf("Turn around!");
}
I read about loops and ifs, but my head do not make klick.
Thanks for reading,
hjerteblod
Assuming you want to never exit the game. If so, try this code -
#include <stdio.h>
int main()
{
char answer;
while(1){
printf("Move!\n");
printf("Is there a wall?\n");
scanf(" %c", &answer);
if (answer == 'Y'){
printf("Turn around!\n");
}
}
return 0;
}
"Y" is a string with two characters, answer[0] is a character, you cannot assign a string to a character. So you can change this code like this answer[0] = 'Y'.
By the way, you are better to return an int value in the function main.
include <stdio.h>
int main(){
// your code here
return 0;
}
"N" is a string literal, which evaluates to a pointer to the first element of the string literal "Y" in memory. If you try to assign it to answer[0] you invoke undefined behavior, since you assign a address value to char objects.
The same goes for answer[1] = "N";.
Both assignments, answer[0] = "Y"; and answer[1] = "N"; should have give you a warning, like this from GCC:
warning: assignment to 'char' from 'char *' makes integer from pointer without a cast
Never ignore compiler warnings.
You don't need an array at all, use a single char for answer.
You need an infinite loop for always going further or turning back from a wall, here implemented by while (1).
Note that this is an unfinished algorithm. In a real production program you need a condition to break out of the loop. But just for the sake of your issue, here is want I think you need:
#include <stdio.h>
int main (void)
{
char answer;
while (1)
{
printf("Move!\n");
printf("Is there a wall?\n");
if ( scanf(" %c", &answer ) != 1 )
{
fputs("Error at input!", stderr);
return 1;
}
if ( answer == 'Y' )
{
printf("Turn around!\n");
}
}
}
Side Notes:
Always check the return value of input functions such as scanf() if an error occurred.
void main() is not standard compliant. Use a return type of int and declare the parameter list of type void instead of to leave it empty.
I recommend you to read a good C starting book, f.e. Modern C by Jens Gustedt or The C Programming Language Second Edition by the inventors of C.
For more information about undefined behavior, take a look at this SO question:
Undefined, unspecified and implementation-defined behavior
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am a newbie to C Language. For a my assignment, I wrote this simple code to Print the student grade according to the input marks.
main(){
char grade;
grade = grade_calc(90);
printf("Your Grade is ", grade);
}
char grade_calc(int marks){
if(marks >= 75){
return "A";
}
else {
return "B";
}
}
But it shows error in Function starting line (int marks).
functions.c [Warning] return makes integer from pointer without a cast
Can anyone help me, why it this error happens?
This should do it.
int main(){
char grade;
grade = grade_calc(90);
printf("Your Grade is %c", grade); //%c specify char
// ^^
}
char grade_calc(int marks){
if(marks >= 75){
return 'A';
// ^ ^
}
else {
return 'B';
// ^ ^
}
}
In case you want to know more: C format specifiers.
Also, your return type is conflicting(char vs char*).In case you don't know, "A" is a char* (string) and 'A' is a char (you can learn more about the differences here
. Last but not least, don't forget that main() return int and functions need to be defined before used.
This is the declaration of printf
int printf(const char *format, ...)
printf takes the arguments (what you send to it in the parenthesis) and print it on the screen.
but, printf need to know where to print from (aka what bits you want to print), when to stop and which format are we talking about.
for example:
if we takes a int printf needs to know where is it to see its value.
which type it (int) so printf know to stop printing after 4 bytes. and again the type(int) so the bits will represent as numbers and not chars or floats
every type has its wildcard:
%d for int
%c for char
%s for strings
%f for float
you can look it up
also you need to return a char from the function
so you need to return this:
return('a'); and not return ("a");
so,
"a"
means string literal so the function returns char * and not char.
'a'
means value of the char a
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm a new person who loves to play around with coding. Recently I was going through a course on edx, and one of the exercises I need to complete has this small code snippet that keeps on giving Segmentation fault. I have taken out the faulty bit (everything else compiles nicely)
#include <stdio.h>
#include <string.h>
#include <cs50.h>
#include <ctype.h>
#include <stdlib.h>
int main (int argc, string argv[])
{
if (argc == 2 && isalpha(argv[1]))
{
int a = 0;
while (argv[1][a] == '\0')
{
a++;
printf("%c\n", argv[1][a]);
}
}
else
{
printf("Usage: ./programname 1-alphabetical word\n");
return 1;
}
}
The problem seems to be here: argv[1][a] but I can't for the life of me find out what, and how to fix it.
(1) isalpha(argv[1]) is wrong. This function expects a single character, but you are passing a pointer-to-string. That will certainly not give you any kind of expected result, and it's probably Undefined Behaviour into the bargain. You either need to loop and check each character, use a more high-level library function to check the entire string, or - as a quick and probably sense-changing fix - just check the 1st character as BLUEPIXY suggested: isalpha( argv[1][0] ) or isalpha( *argv[0] ).
(2) Your while condition is wrong. You are telling it to loop while the current character is NUL. This will do nothing for non-empty strings and hit the next problem #3 for an empty one. You presumably meant while (argv[1][a] != '\0'), i.e. to loop only until a NUL byte is reached.
(3) You increment index a before trying to printf() it. This will index out of range right now, if the input string is empty, as the body executes and then you immediately index beyond the terminating NUL. Even if the loop condition was fixed, you would miss the 1st character and then print the terminating NUL, neither of which make sense. You should only increment a once you have verified it is in-range and done what you need to do with it. So, printf() it, then increment it.
2 and 3 seem most easily soluble by using a for loop instead of manually splitting up the initialisation, testing, and incrementing of the loop variable. You should also use the correct type for indexing: in case you wanted to print a string with millions or billions of characters, an int is not wide enough, and it's just not good style. So:
#include <stddef.h> /* size_t */
for (size_t a = 0; argv[1][a] != '\0'; ++a) {
printf("%c\n", argv[1][a]);
}
isalpha(argv[1]) looks incorrect and should probably be isalpha(argv[1][0])
isalpha takes a character but you entered in a string to the function
another thing that sticks out as wrong is argv[1][a] == '\0' the ==
should be != this will mean that the while loop will stop once it hits the \0
perhaps
if (argc == 2)
{
int a = 0;
while (argv[1][a] != '\0')
{
if (isalpha(argv[1][a])
printf("%c\n", argv[1][a]);
a++;
}
}
may be what you are looking for?
The only reason for the segmentation fault I see is this subexpression of the if statement
if (argc == 2 && isalpha(argv[1]))
^^^^^^^^^^^^^^^^
There is specified an argument of an incorrect type. The expression argv[1] has the type char * while the function requires an object of character type that is interpreted as unsigned char and promoted to the type int.
So when the promoted argument has a negative value (except the EOF value) the function isalpha has undefined behavior.
From the C Standard (7.4 Character handling <ctype.h>)
1 The header <ctype.h> declares several functions useful for
classifying and mapping characters.198) In all cases the argument is
an int, the value of which shall be representable as an unsigned
char or shall equal the value of the macro EOF. If the argument has
any other value, the behavior is undefined.
You should write the if statement either like
if (argc == 2 && isalpha( ( unsigned char )argv[1][0] ) )
or like
if (argc == 2 && isalpha( ( unsigned char )*argv[1] ) )
Also there is a bug in the while statement that will execute never if the argument is not an empty string. I think you mean the following
int a = 0;
while ( argv[1][a] != '\0' )
{
printf("%c\n", argv[1][a]);
a++;
}
or for example like
int a = 0;
while ( argv[1][a] )
{
printf("%c\n", argv[1][a++]);
}
This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 5 years ago.
char str[6];
do
{
printf("Enter the string you wanna check:");
scanf("%s", str);
}
while(str != "exit");
Why does this not work?
str will never equal "exit", because you're comparing the addresses of two different sections of memory. You probably want to compare the contents of the strings, for which there is a function strcmp().
"exit" is a char[5] generated by the compiler at some address in the data segment. This address is definitely different from the address of str, as two different objects cannot occupy the same location in memory.
The != operator between expressions of type char[] compares two pointers. These two pointers are the address of "exit" and the address of str, which, as I have already explained, will never be equal.
So, the expression str != "exit" will never evaluate to true. Which brings us to another point: your compiler should have issued a warning about this condition being always false. Which means that you are trying to program without -Wall. Don't do this, you are never going to get very far. Always use the highest warning level, and when you see warnings, always fix them.
To correct the problem, do as user3121023 suggested in a comment, and use strcmp() to compare strings.
The short answer is: it does not work because you must use strcmp(str, "exit") to compare the strings and loop for as long as the return value of strcmp() is not 0.
The long answer is: there are more problems in this little code fragment:
The array into which you read a word is very short and you do not limit the number of characters scanf() is likely to store there. Any user input longer than 5 non space characters will cause undefined behavior.
You do not check the return value of scanf(). A premature end of file, such as redirecting input from an empty file, will cause an infinite loop.
Here is how the code can be written in a safer way:
#include <stdio.h>
int main(void) {
char str[80];
for (;;) {
printf("Enter the string you wanna check:");
if (scanf("%79s", str) != 1 || strcmp(str, "exit") == 0)
break;
}
return 0;
}
As suggested above, use strcmp from the <string.h> header file.
char str[6];
do {
printf("Enter the string you wanna check:");
scanf("%s", str);
} while(!strcmp(str, "exit"));
Try :
#include <stdio.h>
#include <string.h>
int main() {
char str[6];
do
{
printf("Enter the string you wanna check:");
scanf("%s", str);
}
while(strcmp(str, "exit") != 0);
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
When I run this code, I get a segmentation fault. I'm sure I'm doing the pointers wrong, but I'm not sure why or how to fix it.
I also included the question I'm trying to answer in picture form.
#include <stdio.h>
#include <stdlib.h>
char * repeat_characters(char *s, int n) {
printf("%s", *s);
char temp;
int length = 0;
int i = 0;
int j = 0;
int k = 0;
char * newString;
while(s[length]) {
length++;
printf("%d", length);
} // finds length of string
newString = (char*) malloc(length*n*sizeof(char));
while(i++ < i*n) {
temp = s[i];
while (j++ < n) {
newString[k] = temp;
printf("%c", temp);
k++;
}
}
printf("%s", newString);
return newString;
}
int main () {
char * string[100];
int numReps = 0;
printf("Enter a string: ");
scanf("%s", string);
printf("\nEnter number of repetitions: ");
scanf("%d", &numReps);
repeat_characters(*string, numReps);
return 0;
}
One of your jobs as a questioner is to shorten your program to the minimum that demonstrates a problem. For instance, the following would give a segmentation fault:
#include <stdio.h>
char * repeat_characters(char *s, int n) {
printf("%s", *s);
return NULL;
}
int main () {
char * string[100];
scanf("%s", string);
repeat_characters(*string, 0);
return 0;
}
Lots of kinds of problems could be pointed out by compiler warnings. So turn those warnings on. If you're using gcc, then try something like gcc -Wall -Wextra -Werror main.c (or look in your compiler's documentation.)
(The -Werror will turn the warnings into errors, and keep you from accidentally ignoring a warning, which I'd say is a good habit for both learners and experts alike.)
printf("%s", *s);
format '%s' expects argument of type 'char*', but argument 2 has type 'int'
Here you have a parameter char *s. Depending on context could either be a pointer to a single character, or a pointer to the first character of a multiple-character sequence.
C strings operate on the convention that it's a multiple character sequence, and that the range of characters is eventually terminated by a '\0' (or 0-valued character). So when you call printf you must be sure that the character pointer you pass in is to such a validly formed sequence.
You are passing in *s, which dereferences the pointer-to-a-character to make it into a single character. If you want to print a single character, then you'd need to use %c, e.g. printf("%c", *s);. But you want to print a C string, so you should drop the dereferencing * and just say printf("%s\n", s). (You will likely want \n to output a newline, because otherwise your prints will all run together.)
(Note: The reason C without warnings didn't complain when you passed a character where a character pointer was expected is due to the "weirdness" of functions like printf and scanf. They don't have a fixed number or type of arguments that they take, so there is less checking...warnings help pick up the slack.)
scanf("%s", string);
format '%s' expects argument of type 'char*', but argument 2 has type 'char**'
Here you have the problem that you've declared s as char * string[100];, which is an array of character pointers, not an array of characters. The duality of a C array being able to behave like a pointer to its first element takes some getting used to, but if you say char string [100]; then string[0] is a char and string can "decay" to a char* synonymous with &string[0]:
Is an array name a pointer?
while(i++ < i*n)
operation on 'i' may be undefined
The compiler is making a technical complaint here, about modifying the variable i in an expression that also uses i. It's warning about whether the i in i*n would see the value before or after the increment. Avoid this kind of expression...and when-and-if the time comes where you care about what you can and can't do like this, read about sequence points.
But put that aside. What did you intend here? Take the nuance of ++ out of it...what about just while (i < i * n)? When would that be false? Why would it be relevant to solving the problem?
Look through your code and perhaps try commenting it more. What are "the invariants", or the things that you can claim about a variable that would be true on each line? If you were asked to defend why the code worked--with no compiler to run it to see--what would be giving you the certainty that it did the right thing?
Then step through it with a debugger and examples, and check your intuition. If you step over a line and don't get what you expect, then that's when it may be time to start thinking of a question to ask which draws the focus to that line.
There's other issues raised in the comments (for instance, that your malloc() doesn't include space for the terminator, and even once you add in 1 for that space you still have to write a '\0' into it...). Generally speaking your program should perform as many free()s as it does malloc()s. Etc. But hopefully this points you in the right direction for the assignment.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I was doing an assignment for my C class in school and I hit a little snag.
#include <stdio.h>
char stringToUpper(char * sName )
{
while(*sName != '\0')
{
stringToUpper (* sName);
++* sName;
}
}
int main()
{
char str[50];
char * sName;
printf("Please enter your name ");
scanf("%s", str);
printf("Hello %s ", str);
sName = str;
stringToUpper(sName);
printf("Name in uppercase: %s ", sName);
}
I tried looking for other solutions already, however I found that everyone else's problems were much more advanced than the level I'm at and really just couldn't follow it. I've still a little new at working with pointers and still a little confused about how they work (only a few weeks into the class) so I feel like the issue has something to do with that. I'm almost certain that the issue has something to do with the while statement.
This is the error I get:
Unhandled exception thrown: read access violation.
sName was 0x41.
If there is a handler for this exception, the program may be safely continued.
Thanks in advanced for whatever help I receive.
Your stringToUpper function has some issues:
while(*sName != '\0')
{
stringToUpper (* sName);
++* sName;
}
You could be calling toupper to change to upper case and assigning the value back to *sName instead of having the function call itself. In fact, the call you had is incorrect because you're passing a char to a function expecting a char *. In the next iteration of stringToUpper, it attempts to dereference that invalid pointer which causes the crash.
You should be incrementing sName (which points to the current character), not *sName.
The corrected version:
while(*sName != '\0')
{
*sName=toupper(*sName);
++sName;
}