I have the following code:
void toCapital(char name[], int size){
int i = 0;
char *wholeName = name;
for (i = 0; i < size ; i++){
wholeName[i] = toupper(wholeName[i]);
printf("%c", wholeName[i]);
}
}
main()
{
char miNombre[] = "Jason Martin Marx";
toCapital(miNombre, sizeof(miNombre));
}
And the output is:
JASON MA
This code takes a char array and converts all the strings inside into upper case. However, for some reason it stops halfway. Even if i increase the number of times to run the loop, it just adds gibberish at the end instead of the following letter.
If i was to edit the array into something like "Jason Martin Marx Jason Martin Marx" (doubling the string size) then it would print out the upper cased string once as "JASON MARTIN MARX" but not the second time.
Here is the whole code as requested:
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
void myName(char name[], int size){
int i;
for (i = 0; i < size -1; i++){
char currentLetter = name[i];
if (currentLetter == 'a' || currentLetter == 'e' || currentLetter == 'i' || currentLetter == 'o' || currentLetter == 'u' ||
currentLetter == 'A' || currentLetter == 'E' || currentLetter == 'I' || currentLetter == 'O' || currentLetter == 'U'){
printf("Character [%c] located at position %i is a vowel\n", currentLetter, i);
}
else if (currentLetter == ' '){
printf("Character [%c] located at position %i is a space\n", currentLetter, i);
}
else if (currentLetter == '$' || currentLetter == '%'){
printf("Character [%c] located at position %i is a symbol\n", currentLetter, i);
}
else{
printf("Character [%c] located at position %i is a consonant\n", currentLetter, i);
}
}
}
void pyramidA(char name[], int size){
int i;
char *wholeName = name;
int pointer = size-1;
char spaces[80] = "";
for (i = 0; i < (size / 2) ; i++){
printf("%i %s [%s] \n", pointer, spaces, wholeName);
wholeName++; ///erases first letter
wholeName[strlen(wholeName) - 1] = '\0'; /// erases last letter
pointer = pointer - 2;
strcat(spaces," ");
}
}
void toUpper(char name[], int size){
int i = 0;
char *wholeName = name;
printf("%s", wholeName);
for (i = 0; i < size ; i++){
wholeName[i] = toupper(wholeName[i]);
printf("%c", wholeName[i]);
}
}
main()
{
char miNombre[] = "Jason $ Martin % Marx ";
myName(miNombre, sizeof(miNombre));
printf("\n");
pyramidA(miNombre, sizeof(miNombre));
printf("\n");
toUpper(miNombre, sizeof(miNombre));
}
The problem is quite simply that you are modifying the string yourself. You probably think that assigning a pointer to another pointer creates a copy, but it doesn't:
char *wholeName = name;
// …
wholeName[strlen(wholeName) - 1] = '\0'; // <- modifies string in 'name'
If you want a temporary copy of name in wholeName, you must duplicate it, e.g.:
char *wholeName = malloc(size);
name = strcpy(wholeName, name);
// at the end of the function:
free(name);
It would be good style to check the return value of malloc. Also, you must free the same pointer that was returned by malloc, and since you do wholeName++ inside the loop I recycled the name pointer above to store the starting position. (The naming of the pointers is now quite misleading.)
Another thing you can do on gcc is create the output of the preprocessor by compiling with the -E option. There might be something going on that is not obvious by looking at the code before compiling. I ran your code and the output is not the same as your are getting. gcc -E foo.c -o foo.i. Edit foo.i and see if your code has been morphed by the preprocessor in any way.
================ output below ==================
JASON MARTIN MARX
The result may be compiler-dependent:
$ gcc -std=c99 -pedantic test.c
test.c: In function 'toCapital':
test.c:6:5: warning: implicit declaration of function 'toupper' [-Wimplicit-function-declaration]
test.c:7:5: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
test.c:7:5: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
test.c: At top level:
test.c:11:1: warning: return type defaults to 'int' [enabled by default]
Here's a result from testing the resulting binary on my end:
bash-3.2$ ./a.out
JASON MARTIN MARX^#bash-3.2$
Other than the warnings, I think using sizeof() on an array declared on the stack should be okay. I think your problem is elsewhere, but I don't know where.
EDIT
Now that we have all the code, your function pyramidA() is manipulating the contents of miNombre. That's why your string is truncated.
Use strcpy() within the functions to work with a copy of the string miNombre. This leaves miNombre unchanged.
Related
I need to write a function that search inside a string a sequence of letters from the abc ( not numbers) remove them and leave only the first and last two of the sequence. For example if the input string is: dabcemoqmnopqrrtaduvwxaz the output should be: da-cemoqm-rrtadu-xaz
Or is the input is : dabcefLMNOpQrstuv567zyx, the output is : da-cefL-OpQr-v567zyx.
I have a main file abc.c and abc_functions.c.
I am getting a few errors-
abc.c: In function ‘main’:
abc.c:10:5: warning: implicit declaration of function ‘abc_functions’ [-Wimplicit-function-declaration]
abc_functions(str);
^
/tmp/ccmsgqvg.o: In function `main':
abc.c:(.text+0x5f): undefined reference to `abc_functions'
collect2: error: ld returned 1 exit status
Any ideas?
`
#include "shortend_string.h"
#include <string.h>
void abc_functions (char str[])
{
char str[max_size];
char *dst = str;
int j = 0;
int i;
int curr;
for (i=0; i < strlen(str); i++)
{
if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) /*checking that the sequences involves the abc letters only*/
{
for (curr = i; curr < strlen(str); curr++)
{
if (str[curr+1] != str[curr]+1)/* sequences ending point*/
break;
}
}
if (curr >= i+2) /*if sequences is larger than or equal to 2 modify the string*/
{
dst[j++] = str[i];
dst[j++] = '-';
dst[j++] = str[curr];
i = curr; /*resetting the loop*/
}
else
dst[j++] = str[i];
}
dst[j] = '\0';
return(0);
}
`
`
#include <stdio.h>
#include "abc_functions.h"
int main()
{
char str[max_size];
printf("please enter a string:");
fgets(str, max_size, stdin);
printf("\nThe String is:%s", str);
abc_functions(str);
printf("\nThe output is :%s\n" , str);
return 0;
}
`
Note the first error:
implicit declaration of function ‘abc_functions’
The compiler said you lacked to supply an abc_functions() declaration.
Please check:
abc_functions.h contains the proper declartion.
abc_functions.h base directory is given to the compiler (use -Ipath_to_dir).
Also, whenever asking about compilation failures, it's a good idea to provide the compilation command line.
So i just started coding with C and want to wake a program to know how many sentences there are in a text. However when making an array with a ".", "?" and "!" I get an error when comparing them to my text[i].
My code is as follows:
int main(void)
{
string text = "Hi there, i'm walking through the woods. Oh there is a branch, i need to jump over. I hope i don't fall.";
printf("%c \n", text[39]); // is a "."
printf("%c \n", text[82]); // is a "."
printf("%c \n", text[103]); // is a "."
printf("%c \n", text[-1]); // i would expect a "." here, but it doesn't show when executing the program. (total of 3 sentences)
char scanend[3] = {".", "?", "!"};
int sentences = 0;
for (int i = 0, n = strlen(text); i < n; i++)
{
if (text[i] == scanend[0] || text[i] == scanend[1] || text[i] == scanend[2])
{
sentences++;
}
}
printf("%i\n", sentences);
}
Why do I get an error when comparing these two array's? and how can i compare them without an error?
Thank you for your help!
I suppose that the name string is declared as a typedef name for char *. Otherwise you need to declare the variable text as having the type char * or const char *.
The initializer list in this declaration
char scanend[3] = {".", "?", "!"};
is incorrect. You are trying to initialize objects of the type char with pointers of the type char * to which string literals are implicitly converted.
Either write
char scanend[3] = {".?!"};
or
char scanend[3] = {'.', '?', '!'};
However it would be better to declare the array like
char scanend[] = {".?!"};
and instead of this if statement
if (text[i] == scanend[0] || text[i] == scanend[1] || text[i] == scanend[2])
{
sentences++;
}
to write
if ( strchr( scanend, text[i] ) != NULL )
{
sentences++;
}
Pay attention to that the expression text[-1] used in this call
printf("%c \n", text[-1]);
invokes undefined behavior.
Instead you could write
printf("%c \n", text[strlen( text ) - 1]);
Also the return type of the function strlen is size_t. So the for loop should look like
for ( size_t i = 0, n = strlen(text); i < n; i++)
i wrote the following code in c to print floyd's triangle.
int main()
{
printf("Enter the number of rows you want to have");
int t;
scanf("%d",&t);
int i;
char a[1000] ="";
for(i=1;i<=t;i++)
{
if (i%2!=0)
{
strcat("1",a);
printf("%c\n",a);}
else
strcat("0",a);
printf("%c\n",a);
}
return 0;
}
The program seems fine to me but it stops working as soon as i execute it. Please help
I want to have the output as follows-
1
01
101
0101
10101
and so on
You can construct the string (the bigger one) first and then print only a part of it in each row:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Enter the number of rows you want to have");
int t;
scanf("%d",&t); // You should check the return value...
puts("");
char pattern[t + 1]; // It's a VLA, so you need a C99 compliant compiler or
// use your big array...
// Initialize the string (it's the last row) starting from the last
// char (the null terminator) and stepping back to first. Every row should
// end with a '1', so in the loop, start with it.
int i = t;
pattern[i] = '\0';
while ( i > 0 )
{
pattern[--i] = '1';
if ( i == 0 )
break;
pattern[--i] = '0';
}
// Print only the part needed in each row
char* tmp = &pattern[t - 1];
for ( int i = 0; i < t; ++i, --tmp )
{
printf("%s\n", tmp);
}
return 0;
}
Compile with warnings enabled and you will quickly see that you need to print a with %s (string format), rather than %c (character format). When I compiled your code, I got:
prog.c: In function 'main':
prog.c:16:22: warning: format '%c' expects argument of type 'int', but argument 2 has type 'char *' [-Wformat=]
printf("%c\n",a);
~^ ~
%s
prog.c:20:22: warning: format '%c' expects argument of type 'int', but argument 2 has type 'char *' [-Wformat=]
printf("%c\n",a);
~^ ~
%s
Moreover, your else statement lacks curly braces, which results in only the strcat() to be assumed as its body.
To get the desired output, you should abandon strcat() and index the position you want to assign the bit, like this:
#include <stdio.h>
#include <string.h>
int main()
{
printf("Enter the number of rows you want to have\n");
int t;
scanf("%d",&t);
int i;
char a[1000] ="";
for(i=1;i<=t;i++)
{
if (i%2!=0)
{
a[999 - i] = '1';
printf("%s\n", &a[999 - i]);
}
else {
a[999 - i] = '0';
printf("%s\n", &a[999 - i]);
}
}
return 0;
}
Output:
Enter the number of rows you want to have
4
1
01
101
0101
Notice that 999 is the size of your array, minus 1.
PS: In your posted code: when concatenating the string, you messed up the order of the arguments.
This should give you the output you're looking for:
#include <iostream>
#include <string.h>
int main()
{
printf("Enter the number of rows you want to have: ");
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++)
{
for (int j = 1; j <= i; j++)
{
char a[1000] = "";
if ((i+j) % 2 == 0)
strcat(a, "1");
else
strcat(a, "0");
printf("%s", a);
}
printf("\n");
}
return 0;
}
Since every other line begins with a 0, you could simply recreate the string a per line.
So i'm new to c and I have 2 problems with this code:
#import <stdio.h>
int main(){
char answer;
int playerX = 0;
int playerY = 0;
int done = 0;
char direction[] = "none";
while (done == 0){
printf("Direction:\n");
a = getchar();
if (answer == "u"){
playerY += 1;
} else{
}
printf("Your current position is: %d,%d\n", playerX, playerY);
}
return 0;
}
On line 14 it says "warning: comparison between pointer and integer"
With only 1 input (being u) and nothing else I see this:
Direction:
u
Your current position is: 0,0
Direction:
Your current position is: 0,0
Direction:
First of all, I am assuming you have "#include" instead of "import" in line 1, and "answer" instead of "a" in line 12.
To answer the actual question you have, in C char and string are different. You have a char type variable answer, that you are comparing with the string "u". As a result, the compiler is creating a constant string "u" and comparing the pointer to that string with the char type variable answer. Your check should instead have
if(answer == 'u') {
I have some problems with an example of atoi() function from K&R C 2nd edition. Only characters from 0 to 9 should be used. But somewhere in the logic of my program I do something wrong.
So in there is this function:
#include <stdio.h>
int atoi(char s[]);
int main()
{
int i;
char ch;
char co[50];
int ci[50];
while(ch != EOF )
{
for(i=0;i<50-1 && (ch=getchar()) != EOF && ch != '\n';++i)
{
co[i] = ch;
/*ci[i] = atoi(co[i]);*/ /*bugged*/
ci[i] = atoi(co);
printf("%d \n",ci[i]);
}
if(ch == '\n')
{
co[i] = '\n';
}
++i;
co[i] = '\0';
}
return(0);
}
/* as in the book: */
/* atoi: convert s to integer */
int atoi(char s[])
{
int i, n;
n = 0;
for(i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
{
n = 10 * n + (s[i] - '0');
}
return(n);
}
Here are the errors I'm getting:
|In function 'main':
19|warning: passing argument 1 of 'atoi' makes pointer from integer without a cast [enabled by default]
3|note: expected 'char *' but argument is of type 'char'
||=== Build finished: 0 errors, 1 warnings (0 minutes, 0 seconds) ===|
The
(s[i] = '0')
should read
(s[i] - '0')
(note the minus instead of the equals sign).
This converts the characters '0'..'9' to the numeric values 0..9.
You are also not calling atoi() correctly. It takes a string, not a char. You should probably call it from outside the loop.
And ch isn't the right type (it should be int).
atoi(); function need pointer to string. char* that is the reason warning warning: passing argument 1 of 'atoi' makes pointer from integer without typecase
you declare co like: char co[50]; but calls atoi(co[i]); this is wrong,
notice it says int not char.
an example like:
atoi("1"); is valid but atoi('1'); not valid.
so even co is like "12345678" then atoi(co) correct but atoi(co[i]) not correct.
printf("%c = ",co[i]);
ci[i] = atoi(co[i]);
printf("%d \n",ci[i]);
You are trying to convert a char to int, but a char is an integer value. All you need is
printf("%c = %d\n", co[i], co[i]);
if what you want is the decimal value of the char. If what you're trying to do is convert an ASCII digit to an integer, then
printf("%c = %d\n", co[i], co[i] - '0');
will do.