I'm working on a hangman project, and as you can see in my code, it adds some weird characters to my strings in some case. Not always, but most of the time. (for ex.: MOUSE => MOUSE#
Due to I can't do string comparison, and it's ugly too. Any solutions?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
char animals [8][20] = {"LION" ,"GIRAFFE","OCTOPUS", "RHINOCEROS","CENTIPEDE", "ELEPHANT", "MOUSE", "DOG"};
int i ;
int main() {
srand(time(0));
int choose;
choose = rand()% 7;
int length;
printf("%s", animals[choose]);
length = strlen(animals[choose]);
char result[length];
for(i=0; i< length;i++) {
result[i] = '_' ;
}
printf("%s", result);
while(1) {
printf("\nEnter guess char!: ") ;
char guess ;
scanf(" %c", &guess) ;
guess = toupper(guess) ;
hangman(guess, result, animals[choose], length ) ;
}
return 0;
}
void hangman (char guess, char result[], char word[], int length ){
for(i=0; i< length; i++) {
if(guess == word[i]) {
result[i] = guess ;
}
}
printf("%s", result) ;
if(strcmp(result, word)== 0 ){
printf("gratulation!") ;
}
}
strlen(animals[choose]) doesn't include the '\0' NUL terminating character in the string so you need to add one to length when creating result. You also need to null terminate result like this;
char result[length+1];
result[length] = '\0';
For starters I think you mean
choose = rand() % 8;
^^^
because the array animals is declared like
char animals [8][20] = /*...*/;
^^^
This format specifier "%s" used in this call
printf("%s", result) ;
is designed to output string with terminating zero. However the character array result does not contain a string.
You could write
char result[length + 1] ;
for(i=0; i < length;i++) {
result[i] = '_' ;
}
result[i] = '\0';
Related
Hello, let's say I got 2 strings, "Today is a nice day" and "ao". I want to delete the chars of the 2nd string that appear in the 1st one.
This is my issue:
char c[20];
char p[10];
int i,j;
int l1,l2;
printf("Enter a string \n");
scanf("%s",cd);
printf("Enter another string \n");
scanf("%s",car);
len1 = strlen(cd);
len2 = strlen(car);
for (i=0;i<len1;i++){
for (j=0;j<len2;j++){
if (cd[i]==car[j]){
cd[i]="";
}
}
}
What I want is the 1st string to be like "Tdy is nice dy". So I empty the positions where the elements are the same to reposition it later.
Apparently "cd[i]==car[j]" can't be done on C, I got "Invalid conversion from 'const char*' to 'char'.
So i'm pretty much stuck. I'll thank any help.
1) This is a solution matching your algorithm as close as possible.
All what you need is an extra loop and to replace cd[i]=""; which cannot be compiled with cd[i]=0;. The error given by the compiler relates to expression cd[i]=""; cd[i] is a character type and you cannot assign string "" which has a type const char * to char variable. cd[i] is a character "" is a pointer.
The operation cd[i]=0; gives you want you wanted: I empty the positions where the elements are the same to reposition it later. It replaces the unwanted characters with 0.
#include <stdio.h>
#include <string.h>
int main()
{
char cd[] = "Today is a nice day";
char tmp[] = "Today is a nice day";
char car[] = "ao";
int i;
int j;
int k;
int len1 = strlen(cd);
int len2 = strlen(car);
for (i=0;i<len1;i++){
for (j=0;j<len2;j++){
if (cd[i] == car[j]){
cd[i]=0;
}
}
}
k = 0;
for (i=0; i<len1; i++)
{
if(cd[i] == 0)
{
}
else
{
tmp[k] = cd[i];
k++;
}
}
tmp[k] = 0; /* remember to terminate the tmp */
printf("%s\n", tmp);
strcpy(cd,tmp);
printf("%s\n", cd);
return 0;
}
OUTPUT:
Tdy is nice dy
Tdy is nice dy
Alternatively, instead of clearing unwanted character with 0 you could just skip it. This solution is given below:
#include <stdio.h>
#include <string.h>
int main()
{
char cd[] = "Today is a nice day";
char car[] = "ao";
int i;
int j;
int k = 0;
int skip = 0;
int len1 = strlen(cd);
int len2 = strlen(car);
for (i=0; i<len1; i++)
{
for (j=0; j<len2; j++)
{
if (cd[i] == car[j])
{
skip++; // make note that this character is not needed
}
}
if(skip == 0)
{
cd[k] = cd[i]; // copy the character
k++; // increase the position index
}
else
{
// skip the copy of charcter; clear the skip marker
skip = 0;
}
}
cd[k] = 0; // remember to terminate the new ck string!
printf("%s\n", cd);
return 0;
}
OUTPUT:
Tdy is nice dy
In the str char array below I would first like to locate the first math symbol I see, then I would like to count backwards and remove whatever is between the previous three "_" and remove the three "_". Can I please get some ideas on how to do this?
So this:
xa_55_y_*_z_/_+_x_+
Should turn into:
xa*_z_/_+_x_+
My problem is I don't know how to remove:
_55_y_
Here is the code so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
char str [] = "xa_55_y_*_z_/_+_x_+";
int length = 0;
int decrementor = 0;
int underscore_counter = 0;
int i = 0;
length = strlen (str);
for(i = 0; i < length; i++)
{
decrementor = 0;
underscore_counter = 0;
if(str[i] == '*' || str[i] == '/' || str[i] == '+' || str[i] == '-')
{
decrementor = i;
while(underscore_counter != 3)
{
if(str[decrementor] == '_')
{
underscore_counter++;
printf("underscore_counter is %d \n", underscore_counter);
}
decrementor--;
}
}
}
return 0;
}
You can use strcspn() to find the first operator, which simplifies the problem a little. Then it's just a matter of going backwards and counting the underscores, and then just a matter of outputting the appropriate substrings, e.g.:
int main()
{
char str [] = "xa_55_y_*_z_/_+_x_+";
size_t firstOp = strcspn(str, "*/+-");
size_t len = strlen(str);
size_t i = firstOp;
int underscores = 0;
// go backwards looking for the underscores (or the beginning of the
// string, whichever occurs first)
while (i > 0)
{
if (str[--i] == '_')
underscores++;
if (underscores == 3)
break;
}
// output the first part of the string up to the third underscore
// before the first operator
for (size_t j = 0; j < i; j++)
putchar(str[j]);
// output the rest of the string after and including the operator
for (size_t j = firstOp; j < len; j++)
putchar(str[j]);
// and a linefeed character (optional)
putchar('\n');
}
Sorry for the poorly named i and j variables, hopefully it makes sense.
I am doing this programming problem where I have reverse string of about 30 characters for 10 test cases.
My code is this:-
#include <stdio.h>
#include <string.h>
int main () {
int t;
scanf("%d",&t);
while (t--) {
char str[30];
scanf("%s",&str);
char revStr[30];
int len = strlen(str);
int i = 0;
int j = len-1;
while (i < len) {
revStr[i] = str[j];
i++; j--;
}
printf("%s\n",revStr);
}
return 0;
}
The output gets garbled up if the input string is larger than previous string.
For example,
if last-string had 6 characters, like rocket\0 and new-string, which is fun\0 has 3 characters, the output is funket\0.
char str[30];
scanf("%s",&str);
^ don't pass address of array
Just this would work -
scanf("%29s",str);
Try this:
int t;
scanf("%d", &t);
while (t--)
{
char str[30] = { 0 };
scanf("%s", &str);
char revStr[30] = { 0 };
int len = strlen(str);
int i = 0;
int j = len - 1;
while (i < len) {
revStr[i] = str[j];
i++; j--;
}
printf("%s\n", revStr);
}
You need to make two changes
Firstly change scanf("%s",&str); to
scanf("%s",str);
Secondly, after the while loop, you are not making the last element rev string \0. Add this line before the printf statement.
revStr[i] = '\0';
This should solve your problem.
I m writing a little C program and want to know why my output in the console is "0", "0" [...]? The output i expect is "ab", "ac", [...].
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i;
int j;
char string[] = "abc";
char output[8];
int length = size(&string[0]);
for(i=0; i<length; i++) {
for(j=0; j<length; j++){
char a = string[i];
strcat(output, &a);
char b = string[j];
strcat(output, &b);
printf("%c\n", output);
}
}
return 0;
}
Mistake #1. You have not initialised output[] so strcat() will not validly find a nul terminator to append to.
output[0] = 0;
Mistake #2. strcat() isn't the right way of appending chars anyway.
Mistake #3. Your loop controls aren't right. See below.
Mistake #4. Your length is the size of a char* pointer.
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i, j;
char string[] = "abc";
char output[8];
int length = strlen (string); // corrected
for(i=0; i<length-1; i++) { // amended loop
for(j=i+1; j<length; j++) { // amended loop
output[0] = string [i];
output[1] = string [j];
output[2] = 0; // string terminator
printf("%s\n", output); // uses string type not char
}
}
return 0;
}
Program output:
ab
ac
bc
If I have understood correctly what you are trying to do then the program will look the following way
#include <stdio.h>
int main(int argc, char *argv[])
{
char string[] = "abc";
char output[3];
size_t length = sizeof( string ) - 1;
for ( size_t i = 0; i < length; i++ )
{
for ( size_t j = 0; j < length; j++ )
{
if ( i != j )
{
output[0] = string[i];
output[1] = string[j];
output[2] = '\0';
puts( output );
}
}
}
return 0;
}
The output is
ab
ac
ba
bc
ca
cb
If your compiler does not allow to declare variables within the control statement of the loop then you can declare i and j in the beginning of the program.
size_t i, j;
If you want to include combinations like "aa" then you simply may remove the if statement withing the inner loop.
char a = string[i];
strcat(output, &a);
leads to undefined behavior since strcat expects a null terminated string in the second argument. Same thing applies to:
char b = string[j];
strcat(output, &b);
Perhaps you meant to use:
output[0] = a;
output[1] = b;
output[2] = '\0';
Here's the updated for loop:
for(i=0; i<length; i++) {
for(j=0; j<length; j++){
output[0] = a;
output[1] = b;
output[2] = '\0';
printf("%s\n", output);
// ^^ use %s to print a string, not %c.
}
}
If you want to use strcat you must know that it expects a string not a character and there is an important difference, when you pass &a strcat thinks it is the address of a pointer to a string, and you should get most likely a segmentation fault, here I show your own code, modified to use strcat but you don't really need it for this task.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i;
int j;
char string[] = "abc";
int length = strlen(&string[0]);
for(i = 0 ; i < length ; i++)
{
for(j= i + 1 ; j < length ; j++)
{
/* initialize output to 0 more importantly to have a terminating null byte */
char output[3] = {0};
/*
* create a string and initialize it with 2 char's
* - the first one, the one you want to append to output
* - the second one is required by strcat, to mark the end of the string
*/
char a[2] = {string[i], 0};
strcat(output, a);
/* same as above */
char b[2] = {string[j], 0};
strcat(output, b);
printf("%s\n", output);
}
}
return 0;
}
you could do this without strcat unless you are trying to learn how to use strcat, this is an example of how to do it without strcat.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i;
int j;
char string[] = "abc";
int length = strlen(&string[0]);
for(i = 0 ; i < length ; i++)
{
for(j= i + 1 ; j < length ; j++)
{
char output[3] = {string[i], string[j], 0};
printf("%s\n", output);
}
}
return 0;
}
I've got a block of strings, say "aaa\0bbbb\0ccccccc\0"
and I want to turn them into an array of strings.
I've tried to do so using the following code:
void parsePath(char* pathString){
char *pathS = malloc(strlen(pathString));
strcpy(pathS, pathString);
printf(1,"33333\n");
pathCount = 0;
int i,charIndex;
printf(1,"44444\n");
for(i=0; i<strlen(pathString) ; i++){
if(pathS[i]=='\0')
{
char* ith = malloc(charIndex);
strcpy(ith,pathS+i-charIndex);
printf(1,"parsed string %s\n",ith);
exportPathList[pathCount] = ith;
pathCount++;
charIndex=0;
}
else{
charIndex++;
}
}
return;
}
exportPathList is a global variable defined earlier in the code by
char* exportPathList[32];
when using that function exportPathList[i] contains garbage.
What am I doing wrong?
The answer to this SO question:
Parse string into argv/argc
deals with a similar issue, you might have a look.
You need to know how many strings are there or agree for an "end of strings". The simplest would be to have an empty string at the end:
aaa\0bbbb\0ccccccc\0\0
^^
P.S. is this homework?
First of all, since your strings are delimited by a null char, '\0', strlen will only report the size of the string up to the first '\0'. strcpy will copy until the first null character as well.
Further, you cannot know where the input string ends with this information. You either need to pass in the whole size or, for example, end the input with double null characters:
#include <stdio.h>
#include <string.h>
void parsePath(const char* pathString){
char buf[256]; // some limit
while (1) {
strcpy(buf, pathString);
pathString+=strlen(buf) + 1;
if (strlen(buf) == 0)
break;
printf("%s\n", buf);
}
}
int main()
{
const char *str = "aaa\0bbbb\0ccccccc\0\0";
parsePath(str);
return 0;
}
And you need some realloc's to actually create the array.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 16
char* exportPathList[MAXSIZE] = {0};
size_t pathCount = 0;
void parsePath(char* pathString){
char *ptop, *pend;
ptop=pend=pathString;
while(*ptop){
while(*pend)++pend;
exportPathList[pathCount++]=strdup(ptop);
pend=ptop=pend+1;
}
}
int main(){
char textBlock[]= "aaa\0bbbb\0ccccccc\0";
//size_t size = sizeof(textBlock)/sizeof(char);
int i;
parsePath(textBlock);
for(i=0;i<pathCount;++i)
printf("%s\n", exportPathList[i]);
return 0;
}
The solution I've implemented was indeed adding double '\0' at the end of the string and using that in order to calculate the number of strings.
My new implementation (paths is the number of strings):
void parsePath(char* pathString,int paths){
int i=0;
while (i<paths) {
exportPathList[i] = malloc(strlen(pathString)+1);
strcpy(exportPathList[i], pathString);
pathString+=strlen(pathString);
i++;
}
}
I'd like to thank everyone that contributed.
My Implementation looks like this -> it follows the idea of argv and argc in a main funtion:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char **args = (char**)malloc(100*sizeof(char));
char buff[100], input_string[100], letter;
for(int i = 0; i < 100; i++){
buff[i] = '\0';
input_string[i] = '\0';
}
for(int i = 0; (letter = getchar())!='\n'; i++){
input_string[i] = letter;
}
int args_num = 0;
for(int i = 0, j = 0; i < 100;i++){
if((input_string[i] == ' ')||(input_string[i]=='\0')){
//reset j = 0
j = 0;
args[args_num] = malloc(strlen(buff+1));
strcpy(args[args_num++],buff);
for(int i = 0; i < 100; i++)buff[i] = '\0';
}else buff[j++] = input_string[i];
}
for(int i = 0; i < args_num; i++){
printf("%s ",args[i]);
}
}
-> Every single word in your string can then be accessed with args[i]