Trying to make some basic hangman code to practice learning C but I can't seem to change individual characters in the program
int main(int argc, char *argv[]) {
int length, a, x;
x = 0;
char gWord[100];
char word[100] = "horse";
length = strlen(word) - 1;
for(a = 0; a<= length; a = a + 1){
gWord[a] = "_";
printf("%s", gWord[a]);
}
printf("%s", gWord);
}
when I try to run this it just prints (null) for every time it goes through the loop. It's probably a basic fix but I'm new to C and can't find anything about it online
To print character instead of string change:
printf("%s", gWord[a]);
to:
printf("%c", gWord[a]);
but before that change also:
gWord[a] = "_";
to:
gWord[a] = '_';
The last problem is that you were assigning a string literal to a single character.
Edit:
Also as #4386427 pointed out, you never zero-terminate gWord before printing it later on with printf("%s", gWord). You should change the last line from:
printf("%s", gWord);
to:
gWord[a] = '\0';
printf("%s", gWord);
because otherwise this would very likely lead to a buffer overflow.
This line
printf("%s", gWord[a]);
Must be
printf("%c", gWord[a]);
To print a char, c is the right specifier. s is only for whole strings and takes char pointers.
Are you getting any warning message('s) when compiling your code?
Since you are learning C language, one suggestion - Never ignore any warning message given by the compiler, they are there for some reason.
Three problems in your code:
First:
Assigning string to a character:
gWord[a] = "_";
gWord is an array of 100 characters and gWord[a] is a character at location a of gWord array. Instead, you should do
gWord[a] = '_';
Second:
Using wrong format specifier for printing a character:
printf("%s", gWord[a]);
^^
For printing a character you should use %c format specifier:
printf("%c", gWord[a]);
Third:
Missed adding null terminating character at the end in gWord and printing it:
printf("%s", gWord);
In C language, strings are actually one-dimensional array of characters terminated by a null character '\0'. The %s format specifier is used for character string and by default characters are printed until the ending null character is encountered. So, you should make sure to add '\0' at the end of gWord after the for loop finishes:
gWord[a] = '\0';
Apart from these, there are couple of more things -
This statement:
length = strlen(word) - 1;
I do not see any reason of subtracting 1 from the word length. The strlen return the length of string without including the terminating null character itself. So, the strlen(word) will give output 5. Now you are subtracting 1 from this and running loop till <= length may confuse the reader of the code. You should simply do:
length = strlen(word);
for(a = 0; a < length; a = a + 1){
....
....
Also, the return type of strlen() is size_t and the size_t is an unsigned type. So, you should use the variable of type size_t to receive strlen() return value.
Last but not least, make sure to not to have any unused variables/parameters in your program. You are not using argc and argv anywhere in your program. If you are using gcc compiler then compile it with -Wall -Wextra options. You will find that compiler will report all the unused variables/parameters. So, if not using argc and argv then you should simply give void in the parameter list of main() function.
Putting these all together, you can do:
#include <stdio.h>
#include <string.h>
int main(void) {
size_t length, a;
char gWord[100];
char word[100] = "horse";
length = strlen(word);
for(a = 0; a < length; a = a + 1) {
gWord[a] = '_';
printf("%c", gWord[a]);
}
gWord[a] = '\0';
printf ("\n");
printf("%s\n", gWord);
return 0;
}
Syntactically, your code is alright #Blookey. But logically, no actually.
Let me point out 3 places which are causing the undesired behavior in your code:
gWord[a] = "_"; Observe this line. You have specified the _ in " ". In case you are unaware of this fact, each individual element of a string is a character. And each character is supposed to be given in ' ', i.e., single quotes and not double quotes.
printf("%s", gWord[a]); A similar error again. gWord[a] is a character, not a string. Hence you need to print it using the format specifier %c instead of %s which is for string instead.
A string, any string is supposed to end with a NULL, which is \0 (backslashZERO). That is what differentiates an array of characters from a string. So just add the following line once you finish loading characters into gWord[].
gWord[a] = '\0';
Here is the complete code, just with the 3 changes:
#include<stdio.h>
#include<string.h>
int main(int argc, char *argv[]) {
int length, a, x;
x = 0;
char gWord[100];
char word[100] = "horse";
length = strlen(word) - 1;
for(a = 0; a<= length; a = a + 1){
gWord[a] = '_';
printf("%c ", gWord[a]);
}
gWord[a] = '\0';
printf("\n%s", gWord);
}
Here is the OUTPUT:
_ _ _ _ _ .
_____.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main(int argc, char *argv[]) {
int length, a, x;
x = 0;
char gWord[100] = {0};
char word[100] = "horse"; /*note that if the array in place strlen +1 is not nulled before using strlen you might not get the correct result*/
length = strlen(word) - 1;/*strln will return 5, that is the letters inn the string the pointer is pointing to until the first terminator '\0'*/
for(a = 0; a<= length; a = a + 1){
gWord[a] = '_'; /* if you use "_" it will try to fit in the chars '_' and '\0' to each char slot of the array*/
printf("%c", gWord[a]); /* %s looks for a string to print while here there are single chars to print*/
}
printf("\n");/*you can print the hole string like this */
printf("%s", gWord);
return 0;/*and remember that main function should always have a return value*/
}
Related
I'm just getting started with C and I just started trying to figure out
call by reference in functions. I have noticed an odd result in my output
when using strlen() to iterate over a string and modify its contents. In this
example the result of strlen() is 3, not including the null character,
but if I do not explicitly check for the null character (or use less than the
result of strlen() instead of less than or equals) during the for loop then
it gives a bizarre bit character in the output which I ASSUME is because of the null character?
Please help this noob to understand what is happening here.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void f_test_s(char s[]);
void f_test_s2(char s[]);
int main(){
char s_test[] = "abc";
f_test_s(s_test);
f_test_s2(s_test);
puts("\nTest complete!");
return 0;
}
void f_test_s(char s[]){
puts("Test #1: ");
printf("string before: %s\n", s);
int len = strlen(s);
printf("strlen() = %d\n", len);
int i=0;
for(i=0;i<=len;i++){
if(s[i] != '\0'){
s[i]++;
}
}
printf("string after: %s\n", s);
}
void f_test_s2(char s[]){
puts("\nTest #2: ");
printf("string before: %s\n", s);
int len = strlen(s);
printf("strlen() = %d\n", len);
int i=0;
for(i=0;i<=len;i++){
s[i]++;
}
printf("string after: %s\n", s);
}
output:
Test #1:
string before: abc
strlen() = 3
string after: bcd
Test #2:
string before: bcd
strlen() = 3
string after: cde
Test complete!
If it matters I am using gcc version 7.3.0 on Ubuntu. I am definitely
not an expert with either C, gcc, or Ubuntu.
This is the problem:
for (i = 0; i <= len; i++) {
s[i]++;
}
It should be:
for (i = 0; i < len; i++) {
s[i]++;
}
s[len] is the null char (0). When you removed null char and replaced it with the value of 1, the contents of the array are now {'a', 'b', 'c', 0x1}. And when printf attempts to print s it's going to keep printing characters past the value memory address of the array until it encounters a null char. Technically this is undefined behavior.
Change this:
for (i = 0; i <= len; i++) {
to this:
for (i = 0; i < len; i++) {
since strlen() returns the length of the string. A C string is as long as the number of characters between the beginning of the string and the terminating null character (without including the terminating null character itself).
Your code invokes Undefined Behavior (UB), since you go out of bounds. Standard string functions (like printf()) depend on the NULL terminating character to mark the end of the string. Without it, they do not know when to stop . . .
I'm trying to write a program which converts lower cased alphabet to numerical digits.
a -> 01
b -> 02
...
z -> 26
For the first nine letters I need to put a 0 before the number.
This is my code.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXLEN 128
void s2n(char str[])
{
int i;
char x;
char result[256];
for (i=0; str[i] != '\0'; i++) {
x = str[i];
x = x - 96;
if (x < 10) {
char src[2] = {0, x};
strcat(result, src);
}
else {
char src2[1] = {x};
strcat(result, src2);
}
printf("%s", result);
}
}
int main(void)
{
char str[MAXLEN];
printf("Lower cased string please: ", MAXLEN);
scanf("%s", str);
s2n(str);
return 0;
}
Could you tell me what is wrong with my code??
One problem I see is:
char src[2] = {0, x};
You want to use the character 0, rather than the byte value 0 (NUL):
char src[2] = {'0', x};
Also, you need to NUL terminate your src array:
char src[] = {'0', x, 0};
The NUL termination would need to be done in both cases.
Another problem is your x = x - 96 statement also does not take into account that the character 0 is different from the byte value 0. So
x = x - 96 + '0';
would be better.
You use strcat() on an uninitialized array, result, it doesn't work that way, strcat() looks for the terminating nul byte in it's first parameter, and glues the second parameter from that point.
In your case there is no '\0' in result, calling strcat() with result as the first parameter causes undefined behavior.
You should at least ensure that there is one '\0' in result, you can do that by just setting the first element of result to '\0', like
result[0] = '\0';
Right before the loop starts, also you pass the second paramter src which is an array but is not a string, because it has no terminating '\0', but you actually don't need an array nor strcat().
You can use an index variable and just assing the ith element of the array to the actual character computed from the original value, like
result[i] = x;
Then you don't nul terminate result, which causes undefined behavior when you try to print resutl.
You also passing a parameter to printf() where it's not expecting one, that indicates that you are either silencing or ignoring compiler warnings.
There are many problems in your code, the following code, does what you want
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void s2n(char chr)
{
char result[4];
if (snprintf(result, sizeof(result), "%02d", 1 + chr - 'a') >= sizeof(result))
return;
printf("%s", result);
}
int main(void)
{
char chr;
printf("Lower cased string please: ");
if (scanf(" %c", &chr) != 1)
{
fprintf(stderr, "input error!\n");
return -1;
}
s2n(chr);
return 0;
}
note that no strings are required except the one where you are going to store the result, which you can build easily with sprintf().
I was trying to inverse a string in C. And I met some trouble defining the destination string.
And here are my thoughts: (I am a beginner, so my thoughts might seem laughable in your eyes...)
I define a string data type with unknown length and assign a string to it. (In my case it's str1)
I get the string length of string 1 and increment this value and assign to an integer. (l in my case. The +1 is to compensate the '\0' at the end of the string)
Use this l integer to define a new string which is the destination string. (str2 in my case.)
Use a for loop to copy from the end of str1 to the start of str2 and add a '\0' to the end of str2 to make it a string.
However, when I try to do this in visual studio 2013, it does not let me compile.
I have attached the error message and the code. (Line 15 in the error message is where I define str2 with integer l)
I tried to just put in a number (for example: 100) at the place where integer l was, and the code works.
Can you let me know what is wrong with defining a string with an integer variable and how to do it if there is a way in C, instead of just defining a long enough sting?
Thank you!
#include<stdio.h>
#include<string.h>
int main()
{
/* Reversing a string! */
int l; /* Length of str1 +1 (for the NULL character) */
char str1[] = "This is an unknown length string!";
l = strlen(str1) + 1;
char str2[l]; /* The destination string */
int i, j;
for (i = strlen(str1)-1,j=0; i < strlen(str1) && i >= 0; i--,j++)
str2[j] = str1[i];
str2[j] = '\0';
/* Display str1 and str2 */
printf("The content of str1: %s\n", str1);
printf("The content of str2: %s\n", str2);
return 0;
}
Visual studio doesn't support mix type declaration and variable length arrays. You need to declare all variables in C89 style, i.e at the beginning of your code in main. And dynamically allocate space for str2.
size_t l; /* Length of str1 +1 (for the NULL character) */
int i, j;
char str1[] = "This is an unknown length string!";
l = strlen(str1) + 1;
char *str2;
str2 = malloc(l);
An alternative that doesn't need dynamic memory allocation. It works in this scenario, but it isn't as general a solution (you couldn't sensibly use it to reverse an arbitrary number of strings of different lengths, for example, whereas you can use malloc() and free() to handle that). Your original code uses a VLA — variable length array — which is standard in C99 and optionally supported in C11.
#include <stdio.h>
int main(void)
{
/* Reversing a string! */
char str1[] = "This is an unknown length string!";
char str2[sizeof(str1)];
int len = sizeof(str1);
int i, j;
for (i = len - 2, j = 0; i >= 0; i--, j++)
str2[j] = str1[i];
str2[j] = '\0';
/* Display str1 and str2 */
printf("The content of str1: %s\n", str1);
printf("The content of str2: %s\n", str2);
return 0;
}
How can I read six digits separately, and then append them?
For example:
I want to enter the following digits: 2 3 6 , 7 5
And the expected output would be: "236,75".
I have to do it with only one loop (to read the numbers), and I have to read the numbers with the type char.
Here's what I have so far:
#include <stdio.h>
int main()
{
char c;
char string [6];
printf("Introduce a number\n");
int i = 0;
while (i <=5) {
scanf("%c", &c);
string[i] = c;
i++;
}
printf("%c\n",string);
}
Try something like this:
char string [7];
printf("Introduce a number\n");
int i = 0;
while(i <=5){
scanf("%c", &c);
string[i] = c;
i++;
}
string[i] = '\0';
//printf("%s", string);
I added the '\0' character at string[6], just in case you need that for printing the values for example.
Also, I recommend you to read about cleaning the input buffer when obtaining input from stdin. Hope it helps.
For starters ensure that your int main() is actually returning an integer.
#include <stdio.h>
int main()
{
char c;
char string[7];
char* stringy = string;
printf("Introduce a number\n");
int i = 0;
while (i <=5) {
scanf("%c", &c);
string[i] = c;
i++;
}
string[i] = '\0';
printf("%s\n",stringy);
return 0;
}
Also you want to print your entire string out with a %s format specifier. This also means that you'll need to null terminate your string which can be done by setting the last character in your array to \0.
Also make sure your array has 7 indexes instead of 6, so everything can fit.
#include <stdio.h>
int main()
{
char c;
char string [7];
printf("Introduce a number\n");
int i = 0;
while (i <=5) {
scanf("%c\n", &c);
string[i] = c;
i++;
}
string[i] = '\0';
printf("result: %s\n",string);
return 0;
}
C strings end with a null character, that is '\0'. Therefore you should always append the null character to a character string as the last character since it determines the end of the string. Therefore the line string[i] = '\0'; is necessary (at the end of the while loop, the value of i will be 6, thus pointing to the last element of the character array).
Another correction to your code is the final printf(). You specified the format to be character format ("%c"), which will only output the first character of the string. You should change it to "%s" for printing the whole string.
This program should work since it is a valid C code. If you are having troubles with this code, then it is platform specific. I couldn't run this code on VS2012, but managed to run it on a GNU C Compiler. Try running the code on an online C compiler, it should work just fine.
This is a follow-up to my previous question . I succeeded in implementing the algorithm for checking umlauted characters. The next problem comes from iterating over all characters in a string. I do this like so:
int main()
{
char* str = "Hej du kalleåäö";
printf("length of str: %d", strlen(str));
for (int i = 0; i < strlen(str); i++)
{
printf("%s ", to_morse(str[i]));
}
putchar('\n');
return 0;
}
The problem is that, because of the umlauted characters, it prints 18, and also makes the to_morse function fail (ignoring these characters). The toMorse method accepts an unsigned char as a parameter. What would be the best way to solve this? I know I can check for the umlaut character here instead of the letterNr function but I don't know if that would be a pretty/logical solution.
Normally, you'd store the string in a wchar_t and use something like ansi_strlen to get the length of it - that would give you the number of printed characters as opposed to the number of bytes you stored.
You really shouldn't be implementing UTF or Unicode or whatever multibyte character handling yourself - there are libraries for that sort of thing.
On OS X, Cocoa is a solution - note the use of "%C" in NSLog - that's an unichar (16-bit Unicode character):
#import <Cocoa/Cocoa.h>
int main()
{
NSAutoreleasePool * pool = [NSAutoreleasePool new];
NSString * input = #"Hej du kalleåäö";
printf("length of str: %d", [input length]);
int i=0;
for (i = 0; i < [input length]; i++)
{
NSLog(#"%C", [input characterAtIndex:i]);
}
[pool release];
}
You could do something like
for (int i = 0; str[i]!='\0'; ++i){
//do something with str[i]
}
Strings in C are terminated with '\0'. So it is possible to check for the end of the string like that.
EDIT: What locale are you using?
If you are going to iterating over a string, don't bother with getting its length with strlen. Just iterate until you see a NUL character:
char *p = str;
while(*p != '\0') {
printf("%c\n", *p);
++p;
}
As for the umlauted characters and such, are they UTF-8? If the string is multi-byte, you could do something like this:
size_t n = strlen(str);
char *p = str;
char *e = p + n;
while(*p != '\0') {
wchar_t wc;
int l = mbtowc(&wc, p, e - p);
if(l <= 0) break;
p += l;
/* do whatever with wc which is now in wchar_t form */
}
I honestly don't know if mbtowc will simply return -1 if it encounters a NUL in the middle of a MB character. If it does, you could just pass MB_CUR_MAX instead of e - p and do away with the strlen call. But I have a feeling this is not the case.