I have an array of chars that I would like to set to 1 variable. How would I go about doing this. For example I would have the following code:
char list[5] = {'B','O','B','B','Y'};
how would I have it so that I could set it to a variable to have it so that:
char *name = "BOBBY"
pulling the values from the list shown above.
In addition to the other answers, there is a simpler solution for systems conforming to POSIX 1-2008, such as linux and OS/X:
char *name = strndup(list, sizeof(list));
Since the string is not null terminated you cannot assume that functions like strcpy will succeed - you will need to do something in O(n) that copies each character one by one:
char *str = NULL;
int len_orig = sizeof(list);
int i;
str = malloc(len_orig+1);
if(!str)
{
perror("malloc");
exit(EXIT_FAILURE);
}
for(i = 0; i < len_orig; i++)
{
str[i] = list[i];
}
str[len_orig]=0;
// use str...
free(str);
char* temp = malloc(sizeof(char) * 6); // 6 because 5 + 1 for null terminator
for(int i = 0; i < 5; ++i)
temp[i] = list[i];
temp[5] = '\0';
You can do this, I'd not use strcpy for this as your array is not null-terminated.
Related
int main(){
char* str = "bake", *temp = str;
char alpha [] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
for (int i = 0 ; temp[i] != '\0'; i++) {
for (int j = 0; alpha[j] != '\0'; j++) {
temp[i] = alpha[j];
printf("%s\n",temp);
}
temp = str;
}
return 0;
}
Why am I trying to replace a character in a particular location it falls to me?
i want it print me like that
i = 0 (index 0 he change only the first char).
aake
bake
cake
dake
....
i = 1(index 1 he change only the second char).
bake
bbke
bcke
bdke
....
i don't understand why temp[i] = alpha[j]
not work... what i need to do that i can change the char.
thank you a lot for helps
![enter image description here][1]
[1]: https://i.stack.imgur.com/v0onF.jpg
As said in the comments, there are a couple of mistakes in your code. First of all, as stated by bruno you cannot modify a literal string. Secondly, when you write *temp=str you are saying "the pointer temp now points to the same adress as str", in short, doing this, if you modify the array in temp you will modify the array in str as well, and vice-versa, because they are the same.
Below you have a possible solution using malloc to create a new array in temp and strcpy to copy str to temp after each outter cycle
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char str[]= "bake",*temp;
temp=malloc((strlen(str)+1)*sizeof(char));
strcpy(temp,str);
char alpha [] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
for (int i = 0 ; temp[i] != '\0'; i++) {
for (int j = 0; alpha[j] != '\0'; j++) {
temp[i] = alpha[j];
printf("%s\n",temp);
}
strcpy(temp,str);
}
return 0;
}
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int len = 3; // length of word
char * word = "cat"; // word to be sorted
char sortedWord[len];
int i, j, temp;
// store chars from 'word' to an array 'sortedWord[]'
for (i = 0; i < len; i++) {
sortedWord[i] = *word;
word++;
}
// sort the array using bubble sort
for (i = 0; i < len - 1; i++) {
for (j = 0; j < len - i - 1; j++) {
if (sortedWord[j] > sortedWord[j + 1]) {
temp = sortedWord[j];
sortedWord[j] = sortedWord[j + 1];
sortedWord[j + 1] = temp;
}
}
}
printf("%s\n", sortedWord);
}
The focus of this question is the variable 'len'. If I were to define len to be equal to 3, then the output is as expected (i.e. "act"). However, I want to be able to find the length without explicitly defining it.
I have tried to define len as:
int len = strlen (word);
However, the output is not as expected. It would give me results such as actW?, actX?, and so on.
This same behavior occurs when I try to define len as:
int len;
for (len = 0; *word != '\0'; len++) {
word++;
}
Surprisingly, if I were to print the the variable len right after explicitly defining it, it would also behave the same way.
int len = 3;
printf("Length: %d\n", len); // will cause the output to be different
I am sure that I am missing a fundamental concept, but I am not sure on an approach to resolve this problem. Thanks in advance!
Your storeWord is not null terminated causing undefined behavior, add the null terminator and it will no longer behave erratically.
And also, if you increment the word pointer, it will end up pointing to the null terminator of the original string, so don't do that. Instead, use the index to access elements.
char sortedWord[len + 1]; // One more for the '\0'
int i, j, temp;
// store chars from 'word' to an array 'sortedWord[]'
for (i = 0; i < len; i++) {
sortedWord[i] = word[i];
}
storeWord[len] = '\0';
One more thing, when writing pointers to string literals, use const to prevent accidentally modifiying them, since that is undefined behavior too, so
const char *word = "cat";
I have two strings:
char *str1 = "this is a test";
char *str2 = "ts bd a";
I'm trying to write a function that returns a new string with the same chars from the two string without duplicates (also ' ' is duplicate). eg.:
char *retStr = GetSameChars(str1, str2); //returns "ts a";
How can I do that?
What I'm tried:
char *GetSameChars(char str1[], char str2[]) {
int found = -1, i , j = 0, biggest, index = 0;
char *retArr, *star = '*';
int str1Len, str2Len, count = 0;
str1Len = strlen(str1);
str2Len = strlen(str2);
biggest = str1Len > str2Len ? str1Len : str2Len;
retArr = (char *)malloc(sizeof(char) * count);
for (i = 0; i < str1Len; i++) {
for (j = 0; j < str2Len; j++) {
if (str1[i] == str2[j] && found == -1) {
count++;
found = j;
} else
if (str2[j] == str2[found])
str2[j] = star; //Throw an exception
}
found = -1;
}
retArr = (char *)malloc(sizeof(char) * count);
j = 0;
for (i = 0; i < str2Len; i++)
if (str2[i] != '*')
retArr[j++] = str2[i];
for (i = 0; i < str2Len; i++)
printf("%c", retArr[i]);
}
When I tried the line str2[j] = star; I got an exception.
What is my mistake?
My recommendations would be: keep it simple; get to know the C standard library; write less, test more.
Some specific problems with your code: you pass the wrong variable to malloc(); you estimate the answer to fit in the size of the larger of the two strings but it will actually fit into the smaller of the two; you modify an argument string str2[j] = star -- you should be treating the arguments as readonly; you malloc() retArr twice unnecessarily, leaking the first one when you allocate the second; your algorithm simply doesn't work.
Although a lookup table, as others have suggested, would be more efficient, let's use the standard library routine strchr() to solve this problem:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *getSameChars(const char *string1, const char *string2) {
size_t string1_length = strlen(string1);
size_t string2_length = strlen(string2);
size_t shortest = string1_length < string2_length ? string1_length : string2_length;
char *common_pointer, *common = malloc(shortest + 1);
*(common_pointer = common) = '\0';
for (size_t i = 0; i < string1_length; i++) {
// character found in both input strings, but not yet in common string
if (strchr(string2, string1[i]) != NULL && strchr(common, string1[i]) == NULL) {
*common_pointer++ = string1[i];
*common_pointer = '\0';
}
}
return common;
}
int main() {
char *stringA = "this is a test";
char *stringB = "ts bd a";
char *result = getSameChars(stringA, stringB);
printf("%s\n", result);
free(result);
return(0);
}
Your code complains because you are trying to assign a pointer to a char, to get the value inside a pointer you need to use the * operator like so:
*star;
a good way to check if a letter have already appeared(if you want to use it on all of the ascii table then 128) is to use a lookup table. first you will need to declare an array the length of all letters in the alphabet like so:
char lut[26];
If it is a global variable then it will be set to 0, then all you need to do is go to the index of the char you got and mark it as 1, a simple if will later be able to determine if a letter has already appeard.
example:
lut[toupper(somechar) - 'A'] = 1;
In this example you set the char in the lookup table that is equivalent to the somechar variable as 1, marking it has already appeared.
hope this helps.
I am new with pointers on C and I am trying to write a function like strcat() but without using it. I developed the following function:
char cat(char *a, char *b) {
int i=0,cont=0,h=strlen(a)+strlen(b);
char c[h]; //new string containing the 2 strings (a and b)
for(i;i<strlen(a);++i) {
c[i] = *(a+i); //now c contains a
}
int j = i;
for(j;j<strlen(b);++j) {
c[j] = *(b+cont); //now c contains a + b
cont++;
}
return c; // I return c
}
And this is how I call the function:
printf("\Concatenazione: %c", cat(A,B));
It is now working because the final result is a weird character. How could I fix the function? Here there's the full main.
char * strcat(char *dest, const char *src)
{
int i;
int j;
for (i = 0; dest[i] != '\0'; i++);
for (j = 0; src[j] != '\0'; j++) {
dest[i+j] = src[j];
}
dest[i+j] = '\0';
return dest;
}
From your implementation it appears that your version of strcat is not compatible with the standard one, because you are looking to allocate memory for the result, rather than expecting the caller to provide you with enough memory to fit the result of concatenation.
There are several issues with your code:
You need to return char*, not char
You need to allocate memory dynamically with malloc; you cannot return a locally allocated array.
You need to add 1 for the null terminator
You need to write the null terminator into the result
You can take both parameters as const char*
You can simplify your function by using pointers instead of indexes, but that part is optional.
Here is how you can do the fixes:
char *cat(const char *a, const char *b) {
int i=0,cont=0,h=strlen(a)+strlen(b);
char *c = malloc(h+1);
// your implementation goes here
c[cont] = '\0';
return c;
}
You are returning a POINTER to the string, not the actual string itself. You need to change the return type to something like "char *" (or something equivalent). You also need to make sure to null terminate the string (append a '\0') for it to print correctly.
Taking my own advice (and also finding the other bug, which is the fact that the second for loop isn't looping over the correct indices), you end up with the following program:
#include <stdio.h>
char *cat(char *a, char *b) {
int i = 0, j = 0;
int cont = 0;
int h = strlen(a) + strlen(b) + 1;
char *result = (char*)malloc(h * sizeof(char));
for(i = 0; i < strlen(a); i++) {
result[i] = a[i];
}
for(j = i; j < strlen(b)+ strlen(a); j++) {
result[j] = b[cont++];
}
// append null character
result[h - 1] = '\0';
return result;
}
int main() {
const char *firstString = "Test First String. ";
const char *secondString = "Another String Here.";
char *combined = cat(firstString, secondString);
printf("%s", combined);
free(combined);
return 0;
}
c is a local variable. It only exists inside the function cat. You should use malloc.
instead of
char c[h];
use
char *c = malloc(h);
Also, you should add the null byte at the end. Remember, the strings in C are null-ended.
h = strlen(a) + strlen(b) + 1;
and at the end:
c[h - 1] = '\0';
The signature of cat should be char *cat(char *a, char *b);
You will get an error of
expected constant expression
for the code line char c[h];. Instead you should be using malloc to allocate any dynamic memory at run-time like::
char* c ;
c = malloc( h + 1 ) ; // +1 for the terminating null char
// do stuff
free( c ) ;
Your corrected code::
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include <stdlib.h>
char* cat(char *a, char *b) {
int i=0,cont=0,h=strlen(a)+strlen(b), j;
char *c;
c = malloc( h+1 ) ;
for(i;i<strlen(a);++i) {
c[i] = *(a+i);
}
j = 0 ;
for(j;j<strlen(b);++j) {
c[i] = *(b+cont);
i++ ;
cont++;
}
c[i] = 0 ;
return c;
}
int main() {
char A[1000],B[1000];
char * a ;
printf("Inserisci la stringa 1: \n");
gets(A);
printf("Inserisci la stringa 2: \n");
gets(B);
a = cat(A,B) ;
printf("\nConcatenazione: %s", a);
free(a) ;
getch();
return 0;
}
I'm trying to take a string and break it into "word" components and store that in an array of strings.
"Hello my name is Bill." should give back a char** with elements, "Hello", "my", "name", "is", and "Bill."
My code will compile however I keep encountering a runtime error (I don't get warnings anymore and my debugger gdb doesn't work)>
I'm running on minGW on Window 8.
#include <stdio.h>
#include <stdlib.h>
char** words(char* string)
{
int i = 0;
int j = 0;
int k =0;
int count = 0;
char** stringArray = (char**) malloc(sizeof(char)*30*30);
while( string[i] != '\0' )
{
if(string[i] != ' ')
{
j =0;
while(string[i+j+1] != ' ')
{
j++;
}
i = i+j;
for(k=0; k<=j; k++)
{
stringArray[count][k] = string[i+k];
}
count++;
}
i++;
}
return stringArray;
}
int main()
{
char message[20] = "abcd efgh ijkl mno";
char** wordArray = words(message);
printf("%c\n\n", wordArray[0][0]);
int i =0;
while(wordArray[i])
{
printf("%s\n", wordArray[i]);
i++;
}
printf("\nThe problem is not with the words function");
return 0;
}
There are couple of issues that have been mentioned in the comments.
The allocation should look something like:
#include <ctype.h> // for isspace()
#define MAXSTRLEN 30 // using a symbolic constant
char **stringArray;
int i, j, k;
stringArray = malloc(sizeof(char*) * MAXSTRLEN); // don't cast from malloc
for (i = 0; i < 30; ++i) {
stringArray[i] = malloc(sizeof(char) * MAXSTRLEN);
}
// TODO error checking: malloc could return NULL
while copying the substrings would look like:
i = 0;
j = 0;
while( string[i] != '\0') // go through the whole string
{
while (string[i] != '\0' && isspace(string[i])) {
i++; // skip whitespaces
}
k = 0;
while (string[i] != '\0' && !isspace(string[i])) { // copy word until whitepace or end of string
stringArray[j][k++] = string[i++];
}
stringArray[j][k] = '\0'; // EOS !!!
j++;
}
and printing (j is number of words actually read):
for (i = 0; i < j/*30*/; ++i) { // (!) how to print
printf("%s\n", stringArray[i]);
}
And, yes strtok would also do the job.
In words() you're assigning values to stringArray as a two-dimensional array, and in main() you're reading values from it as an array of pointers. Those are not the same thing.
So you need to change it so that you're consistently treating it as a 2D array, or so that you're consistently treating it as an array of pointers (char* to be exact). Either will work... see the comments above for elaboration.
This code is all wrong.
char** stringArray = (char**) malloc(sizeof(char)*30*30);
First of all, sizeof(char) is always one, second, you don't need to cast a void. So:
char **stringArray = malloc(30 * 30);
But that doesn't make any sense because it's an array of char *, so you should allocate in terms of that:
char **stringArray = malloc(sizeof(char *) * 30);
Or even better:
char **stringArray = malloc(sizeof(*stringArray) * 30);
So now you have an array with 30 char *, but each of those is not initialized, so you need to do that:
for (i = 0; i < 30; i++)
stringArray[i] = malloc(sizeof(**stringArray) * 30);
If you don't do that, you can't access stringArray[count][k].
And then you assume the last element in the array is NULL, but you never set it, so you either do stringArray[count] = NULL at the end of words(), or you do calloc() instead of malloc().
I'm not analyzing the code beyond that; it's just all wrong.