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 4 years ago.
Improve this question
I am using gcc 4.9.2-10 deb8u1 compiler to compile
Here is my code
#include <stdio.h>
int main(){
char *s;
char sa[10] , sb[10];
scanf("%s", sa);
printf("line\n");
scanf("%s", sb);
printf("%s %s", sa, sb);
}
Above code is no any problem if char is under the space provided
However
scanf("%s", s);
printf("line\n");
scanf("%s", sa);
printf("%s %s", s, sa);
Input:
$:
Hu
Result:
line
(null) Hu
Someone could told me what happen about second code wrong .?
I cannot figure out why i cannt input second one .. Thx a lot .!
In you code
char *s;
char sa[10] , sb[10];
you can't do much with s.
scanf("%s", sa);
is ok, provided the input fits. You can jump through a few hoops, reading the inputs in chunks in a loop if it might be longer (see here)
However, in you "However" section of the question you try
scanf("%s", s);
Since s doesn't point to memory - you'd need to have allocated some - you have undefined behaviour, so anything could happen.
I cannot figure out why i cannt input second one ? because s is not initialize and not having any valid address & doing scanf() on that results in undefined behaviour.
First allocate the memory and then scan the user input.
int main() {
char *s; /* its un initialized */
s = malloc(size); /* this you need to do ? specify the size value */
fgets(s,size,stdin);/* its advisable as its not having overflow problem */
printf("%s\n",s);
/* once job is done , free it by calling free(s) */
free(s);
return 0;
}
Use fgets() instead of scanf() to scan the user input for the reason listed in comments.
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 4 years ago.
Improve this question
I'm using the strcmp() fucntions to test how it works.
Ok,there is strcmp(string1,string2) that says us is ti string1 greater or smaller than string2 .
Here is my code to test this function:
#include<stdio.h>
#include<string.h>
char string1[20];
char string2[20];
int main()
{
int test;
printf("Enter 'string1'\n");
scanf("%s",&string1);
printf("Enter 'string2'\n");
scanf("%s",&string2);
test=strcmp(string1,string2);
if(test>0)
printf("String 'string1' is greater than 'string2'\n");
else if(test<0)
printf("String 'string1' is less than 'string2'\n");
else if(test==0)
printf("\n String 'string1'is equal to 'string2'");
printf("\n The value of 'test' is :%d",test);
return 0;
}
the test variable is always 1 and 'string1' is always greater than 'string2' .
pls help
strcmp is unlikely the problem. Here are a few things you can do to troubleshoot the problem.
Make sure to prevent overflow when using scanf.
Make sure that the calls to scanf are successful.
Add a line of code to print what was read so you know the values being passed to strcmp.
You don't need to use &string1 to read a string. Use just string1. Same with string2.
printf("Enter 'string1'\n");
// Read at most 19 characters from the stream, leaving space
// for the null terminator.
if ( scanf("%19s", string1) != 1 )
{
// Problem reading into string1.
printf("Unable to read string1\n");
}
printf("Enter 'string2'\n");
if ( scanf("%19s", string2) != 1 )
{
// Problem reading into string2.
printf("Unable to read string2\n");
}
printf("Input strings...\nstring1: \"%s\", string2: \"%s\"\n", string1, string2);
You should write like this, because the problem is in the scanf:
printf("Enter 'string1'\n");
scanf("%s",string1);
printf("Enter 'string2'\n");
scanf("%s",string2);
Don't use the & when you try read a string/pointer.
E.g:
char *str;
scanf("%s", str);
You can use the fread(string1, 20, stdin) to previne the string overflow
You can try the code here
The problem in your code is that while receiving string from the user , you are storing the string using scanf("%s",&string1) , You need to understand that &string1 and string1 both gives the same address,but they both are very much different.When you increment &string1 ,it points to 80 bytes further from the base address because on incrementing a pointer it points to the same location of its type ,&string1 means base address of whole array while string1 means address of the first element,so when you increment it ,it points to 4 bytes further from the base address.So when you give an address to scanf to store a string ,be careful what type of address you are giving otherwise it may give you some undefined behaviour.In your program just in place of &string1 use string1 in scanf to receive string, the remaining program is correct.
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 4 years ago.
Improve this question
Im trying to read from a file into an array, which is shown in the first for loop. This part of my script works, however i want the answers that the user gives to be copied into the array q.a in the q structure. and the at the end of the script the questions and answers given printed off. Can anyone shed some light on why this isn't working for me?
struct qa{/
char q[40][250];
char a40][250];
};
int main()
{
int a, i, k, l, j;
FILE *fp;
fp = fopen("quest.txt", "r");
struct qa q;
for(i>0;i<=11;i++){
fgets(q.q, 250, (FILE*)fp);
printf("%s", q.q);
scanf("%s", q.a[l][j]);
}
for (i=0;i<11;i++){
strncpy(q.a[j], q.q[k], 250);
}
for (i = 0; i < 11; i++){
printf("%s/n", q.a[l][j]);
}
I get a segmentation fault error when i try and run the script that only started happening when i put the strncpy for loop in.
First of all you never initialize your values : i j k l are never initialized and a isn't even used.
Then you're trying with scanf("%s", q.a[l][j]); to put a char * into a char.
See stacktrace
For debugging purposes install and use valgrind/gdb if you're into cli or any debuggers in your IDE, it will be easier
This is the code I used, if you want to know which lines point to which line of code
Change scanf("%s", q.a[l][j]); to scanf("%s", q.a[l]); and do the same for the last printf
Also remember to compile with flags like -W -Wall -Wextra so that you can get more warnings from the compiler, it can detect most of your mistakes.
This is awful:
for(i>0;i<=11;i++){
fgets(q.q, 250, (FILE*)fp);
printf("%s", q.q);
scanf("%s", q.a[l][j]);
}
with one inconsistency per line!
for(i>0;i<=11;i++) the first element of a for is for assignation so it should never contain a comparison. You want for(i=0; i<11; i++)
fgets(q.q, 250, (FILE*)fp); - q.q is an array of char arrays, when what is expected by fgets is an array of characters. It should be fgets(q.q[i], 250, (FILE*)fp);.
printf("%s", q.q); invokes undefined behaviour, because q.q is an array of array of chars when %s expects a char pointer. It should be printf("%s", q.q[i]);
scanf("%s", q.a[l][j]); %s expects a pointer to an array of characters, and you give it the value of a single character! What you want is scanf("%249s", q.a[i]);
This means nothing:
for (i=0;i<11;i++){
strncpy(q.a[j], q.q[k], 250);
}
j and k are uninitialized automatic variables, so their value is anything. In short you are writing random values at random memory location!
Even the last part is poor:
for (i = 0; i < 11; i++){
printf("%s/n", q.a[l][j]);
}
l is still uninitialized, the end of line is \n with a backslash and not a straight slash, and %s still expects a char pointer... If you want to print the questions and answers, just do:
for (i = 0; i < 11; i++){
printf("%s\n%s\n\n", q.q[i], q.a[i]);
}
it will give you the question on a line, the answer on the following one, and the empty line before next bloc.
TL/DR: you really should consider learning the basics of C language...
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Was talking to a colleague today on one-spot errors - I.e. errors (or at least patterns that should ring an alarm bell) in code that a decent programmer should be able to spot at a single glance like
x = malloc (strlen(y));
while (!feof (f)) {
...
}
char *f(){
char x[100];
...
return x;
}
Who has similar snippets of such patterns? I would suggest anyone who has been on SO for a while will have his personal favourites of those
char *buf;
scanf("%s", buf);
This is wrong, because no memory has been allocated for buf.
char buf[100];
scanf("%s", &buf);
This is wrong, because scanf expects a char *, not a char (*)[n].
char c;
while ((c = getchar()) != EOF)
putchar(c);
This is wrong, because EOF does not fit in the range of a char. Use int instead.
fflush(stdin);
fflush is undefined for input streams, like stdin, albeit this is implemented as an extension in some compilers, like Microsoft C.
#define IN 0;
Do not put semicolons at the end of a #define.
blk = realloc(blk, n);
If realloc fails, any contents in blk will be lost, because realloc will return NULL. To solve the problem, copy the return value into a temporary and only if the temporary is not NULL, copy to the final destination.
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;
}