This is my code:
#include<stdio.h>
#include<stdlib.h>
main(){
char *alf="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!##$%&.",text[64];
int i, alfl=69;
srand(time(0));
for(i=0;i<64;i++)
text[i] = *(alf+rand()%alfl);
printf("%s",text);
}
But at the printf function it print an heart at final of the string.
As others have suggested in the comments (#mbratch and #KerrekSB) you need a null terminator at the end of your string.
Modify your code as follows:
#include<stdio.h>
#include<stdlib.h>
main(){
char *alf="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!##$%&.",text[64];
int i, alfl=69;
srand(time(0));
for(i=0;i<63;i++)
text[i] = *(alf+rand()%alfl);
text[i] = '\0';
printf("%s",text);
}
And it should work, but as #Simon suggested there can be other things that could help improve your code and understanding of C.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 64
int main() { // If you don't add a return type, int is assumed. Please specify it as void or int.
const char *alf="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!##$%&."; // This string cant be assigned to. Make sure that you stay "const-correct".
char text[LEN]; // Please avoid magic numbers here too by using a constant
int i, alfl = strlen(alf); // As #Simon says, it is better to not use magic constants.
srand(time(0));
for(i=0;i<LEN-1;i++)
text[i] = *(alf+rand()%alfl);
text[i] = '\0'; // make sure to null terminate your string.
printf("%s",text);
return 0; // If your return type is int, you must return from the function.
}
Several suggestions:
main should return an int:
int main(void)
{
return 0;
}
You should use strlen to determine the length of strings:
alfl = strlen(alf);
It's easier to use array notation:
for(i = 0; i < 64; i++)
text[i] = alf[rand() % alfl];
If you use text like a string, it must be '\0' terminated:
text[63] = '\0';
Related
Trying to take a lower case string, and create a new string after making characters uppercase
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main (void)
{
string word = "science";
char new_word[] = {};
for (int i = 0, len = strlen(word); i < len; i++)
{
if (islower(word[i]))
{
new_word = new_word + toupper(word[i]);
}
}
}
I am getting "error: array type 'char[0]' is not assignable".
This isn't all, and I am sure with my full program there might be an easier way, but I built out everything else, and the only point that I am struggling with is looping through my string to get a new word that is uppercase.
Any assistance would be greatly appreciated!
char new_word[] = {};
Your new char array has length 0 and any access invokes undefined behaviour (UB) as you access it outside its bounds.
If your compiler supports VLAs:
string word = "science";
char new_word[strlen(word) + 1] = {0,};
if not:
string word = "science";
char *new_word = calloc(1, strlen(word) + 1);
and
new_word[i] = toupper((unsigned char)word[i]);
If you used calloc do not forget to free the allocated memory
Undefined behavior when word[i] < 0
Avoid that by accessing the string as unsigned char
As per C reference about toupper()
int toupper( int ch );
ch - character to be converted. If the value of ch is not representable as >unsigned char and does not equal EOF, the behavior is undefined.
This is not correct, compiler gives error , "error: assignment to expression with array type"
new_word = new_word + toupper(word[i]);
which is not allowed with an array type as LHS of assignment.
changed to
new_word[i] = toupper((unsigned char)word[i]);
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main (void)
{
char word[] = "science";
char new_word[sizeof word] = "";
int i;
for (i = 0; i < sizeof(word); i++)
{
if (islower(word[i]))
{
new_word[i] = toupper(word[i]);
}
else /* for Upper case latter, simply fill the array */
{
new_word[i] = word[i];
}
}
new_word[i] = '\0';
printf("%s", new_word);
}
OUTPUT:
SCIENCE
EDIT:
Just echo comment from solution given by M.M and comment from
David C. Rankin casting is not necessary for this example. read comment below from M.M and David C. Rankin
Removed unsigned char from islower() and toupper()
This is but one way of accomplishing the task. Make sure to come up with your way of doing.
#include <stdio.h>
#include <string.h>
#define MAX_BUFF 128
char *upperCase(char *c) {
//printf("%s, %d", c, strlen(c));
for(int i=0; i<strlen(c) && i<MAX_BUFF; i++) {
c[i] = c[i] - ' '; // convert char to uppercase
//printf(">> %c", c[i]);
}
return c;
}
int main (void)
{
char word[MAX_BUFF] = "science";
char new_word[MAX_BUFF];
printf("in>> %s \n", word);
strcpy(new_word, upperCase(&word[0]));
printf("out>> %s\n", new_word);
}
Output:
in>> science
out>> SCIENCE
Named arrays cannot be resized in C, you have to set the size correctly to start:
size_t len = strlen(word);
char new_word[len + 1]; // leaving room for null-terminator
Note that no initializer can be used for new_word when its size was determined by a function call (a lame rule but it is what it is); and you can take out the len loop variable since it is now defined earlier.
Then set each character in place:
new_word[i] = toupper(word[i]);
but be careful with the surrounding if statement: if that were false, then you need to set new_word[i] = word[i] instead.
(Pro tip, you can get rid of the if entirely, because toupper is defined to have no effect if the character was not lower case).
Lastly, there should be a null terminator at the end:
new_word[len] = 0;
NB. To be technically correct, the call to toupper should be: toupper((unsigned char)word[i]) -- check the documentation of toupper to understand more about this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void initRandom() {
srand(time(NULL));
}
int intUniformRnd(int a, int b){
return a + rand() % (b-a+1);
}
const char* animaisQuatro[] = {"gato", "urso","vaca"};
int main() {
char quatro[4] = {'*' , '*' , '*', '*'};
initRandom();
printf("%s\n", animaisQuatro[intUniformRnd(0,2)]);
for(int i=0;i<4;i++){
printf("%c", quatro[i]);
}
return 0;
}
I have this code that give me a random animal from the array const char* animaisQuatro[] = {"gato", "urso","vaca","lapa"}; from here
initRandom();
printf("%s\n", animaisQuatro[intUniformRnd(0,2)]);
and then I want to put that random animal in another array letter by letter but I don't know how
First I reduced your code to a minimal and reproducible example (something you should do whenever you ask a question):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void initRandom() {
srand(time(NULL));
}
int intUniformRnd(int a, int b){
return a + rand() % (b-a+1);
}
const char* animaisQuatro[] = {"gato", "urso","vaca"};
int main() {
char quatro[4] = {'*' , '*' , '*', '*'};
initRandom();
printf("%s\n", animaisQuatro[intUniformRnd(0,2)]);
for(int i=0;i<4;i++){
printf("%c", quatro[i]);
}
return 0;
}
Then you can proceed like this:
int main() {
char quatro[4] = {'*' , '*' , '*', '*'};
initRandom();
// Get the animal name from a random position
char* name = animaisQuatro[intUniformRnd(0, 2)];
// Iterate four times
for (int i = 0; i < 4; i++) {
// Assign each `name` index to its respective `quatro` position
quatro[i] = name[i];
}
printf("%s", quatro);
return 0;
}
Tip: you can avoiding hardcoding the 2 when calling intUniformRnd. Note that
printf("%d\n", (int) sizeof(animaisQuatro));
printf("%d\n", (int) sizeof(char*));
printf("%d\n", (int) sizeof(animaisQuatro) / sizeof(char*));
outputs
24
8
3
Therefore, you can do
int length = (int) sizeof(animaisQuatro) / sizeof(char*);
int pos = intUniformRnd(0, length - 1);
This way, if you want to add more elements to animaisQuatro, you don't need to change the value inside intUniformRnd.
I want to put that random animal in other array letter by letter
To copy a string to another character array, code could use
// Risky
strcpy(quatro, animaisQuatro[intUniformRnd(0,2)]);
That would overflow quatro[] if it is too small and leads to undefined behavior. (Bad)
A better way to copy and prevent buffer overflow and alert of a failure:
int len = snprintf(quatro, sizeof quatro, "%s", animaisQuatro[intUniformRnd(0,2)]);
if (len >= sizeof quatro) {
fprintf(stderr, "quatro too small.\n");
}
Since C99 and selectively afterword, code could use a variable length array to form a right-size quatro array.
const char *animal = animaisQuatro[intUniformRnd(0,2)];
size_t sz = strlen(animal) + 1;
char quatro[sz];
strcpy(quatro, animal);
Yet since intUniformRnd[] is constant, no need to copy the text, just copy the address to a pointer:
const char *quatro = animaisQuatro[intUniformRnd(0,2)];
I'm new to c. Please help me
Why do I get this error using eclipse
Multiple markers at this line
- request for member 'ToString' in something not a structure or union
- Method 'ToString' could not be resolved
Here is my code
#include <stdio.h>
int main()
{
int s = 5;
int n = 4;
char g = s.ToString();
char l = n.ToString();
printf(g+l);
return 0;
}
s and n are just ints; they don't have a ToString() method. Also, as #remyabel pointed out, char is not the appropriate type for storing a string value, anyway; it stores only one character.
You don't need to convert your ints to strings at all to do what you're trying to accomplish, so you actually want something like this:
#include <stdio.h>
int main()
{
int s = 5;
int n = 4;
printf("%d%d", s, n); // you can't add l to g here!
return 0;
}
// output 54
DEMO
Oh, and please use more descriptive variable names!
EDIT: To save the string, as requested in the comments, you could do this:
char myString[10];
sprintf(myString, "%d%d", s, n); // myString is now "54"
I'd suggest picking up a C tutorial and starting from the beginning. The use of ToString isn't the only thing that's wrong. You could rewrite it this way and it should work (assuming you want to print "54"):
#include <stdio.h>
int main()
{
int s = 5;
int n = 4;
char g = '0' + s;
char l = '0' + n;
printf("%c%c", g, l);
return 0;
}
But this only works as long as s and n are less than 10, and besides is overly complicated since printf is made for formatting and printing values of different types. This would work just as well:
#include <stdio.h>
int main()
{
int s = 5;
int n = 4;
printf("%d%d", s, n);
return 0;
}
If you want to use the string for something else than printing, the answer depends on what you want to do.
I have the task to make a little program with pointers and I am facing a problem with const char*s. The program is meant to count the number of times that a sub-string appears in a main-string. Also, the different positions, where the sub-strings start, should be saved in a char** ptr. This is my little testing code:
#include <stdio.h>
#include <string.h>
main()
{
int i=-1;
int k=0;
char** ptr;
char* str="cucumber";
char* substr="cu";
while(strstr(str, substr)!=NULL)
{
i++;
ptr[i]=strstr(str, substr);
str = strpbrk(str, substr)+1;
k++;
}
printf("%i",k);
}
It should print 2, since the sub-string 'cu' appears 2 times in 'cucumber' - yet, my compiler tells me that I am using chars, when I should use constant ones. Except, I don't know how to do that.
The strstr() function requires them. What should I change?
// note:
// 1) correction to declaration of main()
// 2) addition of return statement
// 3) 'substr' is a poor name choice for a variable, as
// a) it looks like a C lib function (it is a ACL library function)
// b) it does not clearly convey what the variable contains
// 4) clutter in the 'while' loop removed
// 5) 'while' loop is replaced by a 'for' loop so more can be accomplished with less code
// 6) unneeded variables are eliminated
// 7) the 'for' loop stops when there is no possibility of further testStr occurrences
// 8) the printf() clearly indicates what is being printed
#include <stdio.h>
#include <string.h>
int main()
{
char* testStr="cucumber";
char* findStr="cu";
int k = 0;
for( int i=0; strlen(&testStr[i]) >= strlen(findStr); i++)
{
if( strstr(&testStr[i], findStr) != NULL)
{
k++;
}
}
printf("\nnumber of occurrences of %s in %s is %d\n", findStr, testStr, k);
return(0);
}
Allocate memory for storing the pointer values
#include <stdio.h>
#include <string.h>
#define MAX_SUB_STR 10
int main()
{
int i;
int k;
char* ptr[MAX_SUB_STR];
char* str="cucumber";
char* temp;
char* substr="cu";
i = 0;
k = 0;
temp = str;
while(strstr(temp, substr)!=NULL && k < MAX_SUB_STR)
{
ptr[k]=strstr(temp, substr);
temp = ptr[k] + strlen(substr);
k++;
}
printf("%i\n",k);
for (i = 0; i < k; i++)
printf("%p\n",ptr[i]);
return 0;
}
I'm doing the CS50x class and I am stuck at a glitch. I asked them what was going on and no one knew what was going on.
Whenever I try to print a lowercase f it always comes up as ?. Try doing 23 as the argument and abcdefghijklmnopqrstuvwxyz as the input. It's messed up. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main (int argc, string argv[]){
if(argc !=2){
return 1;
}
string x = GetString();
int key = atoi(argv[1]);
for(int a = 0, n = strlen(x); a < n; a++){
char i = key + x[a];
if(islower(x[a])){
if(i > 122){
i = (i-122) + 96;
}
}
if(isupper(x[a])){
if(i > 90){
i = (i-90) + 64;
}
}
printf("%c", i);
}
printf("\n");
return 0;
}
I suspect it's because your char i defaults to signed. When you add 23 to a lowercase letter, anything that is above 104 (being 127-23) is going to wrap around into negatives. Looking at your code, it will stay negative because it fails the subsequent tests and does not get modified.
It's usually best to do char arithmetic with int, then convert back to char... But you could probably fix this by using unsigned char.