Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I've got string as follows
"123 132 244" where that max value for an entry is 255
how can i convert that string to
unsigned char arr[3] = [123, ,132, ,244]
Step 1 : valid the string's format (number - one space - number - one
space ...)
Step 2 : Count the number of space
Step 3 : Allocate the final array
Step 4 : use strtok to have token + sscanf to convert the string to number
Step 5 : return array (+ array size ? It's always useful).
In which step do you have difficulty ?
The expression "123 132 244" is a string literal. If you have access to string functions such as strtok() (defined in strings.h) then parse the string into three char values using strtok() and a string converter such as atoi() or strtol(). If you do not have access to strings.h, then the string to unsigned char conversion will need to be done another way. Here is one example:
const char str[] = {"123 132 244"};
void convertStr(const char *string, unsigned int ucArr[3], size_t size);
int main(void)
{
unsigned int ucArray[3];
convertStr(str, ucArray, sizeof(str)/sizeof(str[0]));
return 0;
}
void convertStr(const char *string, unsigned int ucArr[3], size_t size)
{
int i=0, j=0, k=0;
int accum[3] = {0};//store numeric version of 3 alpha characters
int ex = 0;//use in conversion of single digit value to place value.
int acm = 0;//accumulate integer value of 3 successive integer values
//stored in accum
while(1)
{
if(isdigit(*string))
{
accum[i] = *string - '0';
i++;
}
else
{
//convert
for(k=i-1;k>=0;k--)
{
ex = pow(10, k);
acm += accum[i-k-1]*ex;
}
ucArr[j] = acm;
j++;
i=0;
}
acm = 0;
if(*string == NULL) break;
*string++;
}
}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 10 months ago.
Improve this question
For a school assignment, I am to Create variables in main() that will store the counts and pass pointers to these variables to your functions so that the functions can modify the variables via the pointers. This is a school assignment so rather than someone Give me the answer, I would prefer is someone could help point me in the right direction of using pointers. The Code does work, but not in the way I would like yet.
the code is as follows
void myFunction(int *letters, int *numbers, int *otherCharacters){
}
int main(int argc, char * argv[]) {
// Code for command line argument
if (argc == 2) {
int letters = 0;
int numbers = 0;
int otherCharacters = 0;
int totalCharacters;
int length = strlen(argv[1]);
for (int i = 0; i < length; ++i){
if (isalpha(argv[1][i]) != 0)
++letters;
if (isdigit(argv[1][i]) != 0)
++numbers;
if (isdigit(argv[1][i]) == 0 && isalpha(argv[1][i]) == 0)
++otherCharacters;
}
totalCharacters = letters + numbers + otherCharacters;
printf("%i letters\n%i digits \n%i other characters\n%i characters total\n", letters, numbers, otherCharacters, totalCharacters);
}
I am hoping to rather than change the values of letters, numbers, otherCharacters, and totalCharacters in the main function use pointers to do so in myFunction(). any help on how to use pointers to do so would be much appreciated. Again, I am not asking for an answer, as I would like to complete this assignment myself.
Seems like the function is supposed to look at a string and tell you how many letters, numbers, and other characters there are. It needs to take the counts as pointers, and the string.
void countCharacters(const char *string, int *letters, int *numbers, int *other) {
....
}
Because they are pointers, when incrementing them you need to dereference them first to get their values. Instead of letters++ it would be (*letters)++.
And we can replace the main code to show how you'd call this.
int main(int argc, char * argv[]) {
// Exit early to avoid deeply nesting all the code.
if (argc != 2) {
perror("please supply a string");
return 1;
}
int letters = 0;
int numbers = 0;
int other = 0;
// Pass in the string (already a pointer) and the counts as pointers.
countCharacters(argv[1], &letters, &numbers, &other);
int total = letters + numbers + other;
printf("%i letters\n%i digits \n%i other characters\n%i characters total\n", letters, numbers, other, total);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Can anyone please help me.I want to remove character from char* in C.
For example, char *str this str equals to "apple" and first i remove 1. character and define a new variable then remove 2. character and define new variable and so on until the str ends.
How can ı do that ? I'm completely new to C, and just can't seem to figure it out
Assuming you only need to remove characters from the left.
Because strings in C are arrays of characters, and arrays are pointers to the first element of the array, you can create variables that point to specific indices in you original char array.
For example
char* myString = "apple";
char* subString = myString+1;
printf("%s\n%s\n", myString, substring);
would produce the output
apple
pple
We could generalize this to store all substrings obtained by removing characters from the left in an array of char* pointers (pointers to pointers). Like so:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char** GetSubStrings(char* input)
{
int length = strlen(input);
char** result = calloc(length, sizeof(char*));
for(int i = 0; i < length; i++)
{
result[i] = input + i;
}
return result;
}
int main()
{
char* myString = "apple";
char** subStrings = GetSubStrings(myString);
for(int i = 0; i < strlen(myString); i++)
{
printf("%s\n", subStrings[i]);
}
free(subStrings);
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
So I've got a problem with int and string in C.
My task is to write a function that will output the error rate in string.
For example if the string is "aaabbbcccdxm" then the output should be "1/12".
By "error" I mean any letter from n to z, and any letter from a to m is "good".
I thought that I could do it by using a for loop to check every letter in the string, and then if to add value to int error which would be numbers of bad letters, but I don't know how to convert that "int error" value to string with output error value/string dimension. Any ideas?
You can use printf to format your output. I recommend reading the man 3 printf on a linux machine or from google.
Here is what such a program could look like:
#include <stdio.h>
#include <string.h>
int main()
{
const char * input_str = "aaabbbcccdxm";
int size = strlen(input_str);
int error = 0;
for (int i = 0; i < size; ++i)
{
if (input_str[i] >= 'n')
error++;
}
printf("%d/%d\n", error, size);
return 0;
}
size_t errors(const char *str, const char *legal)
{
size_t errcnt = 0;
while(str && *str)
{
errcnt += !strchr(legal, *str++);
}
return errcnt;
}
int main()
{
char *str = "aaabbbcccdxm";
printf("%zu/%zu\n", errors(str,"abcdefghijklm"), strlen(str));
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
void HorspoolMatching(unsigned char T[], char P[])
{
int i = 0, k, m, n;
int count = 0;
//int *p;
int val;
ShiftTable(P);
m = strlen(P);
n = strlen(T);
i = m - 1;
while(i < n)
{
k = 0;
while((k < m ) && (P[m - 1 - k] == T[i - k]))
{
k++;
}
if(k == m)
{
count++;
i += m;
} else{
val = (int)T[i];
if (val < 0 || val >= MAX) {
i = i + m;
} else {
i = i + table[val];
}
}
}
printf("%d\n", count);
}
...
printf("Enter name of the data file: ");
scanf("%s", filenameFOUR);
FILE *fp4;
fp4 = fopen(filenameFOUR, "r");
if(fp4 == NULL)
{
printf("Error");
exit(0);
}
while((inc = fgetc(fp4)) != EOF)
{
buf[n++] = (char) inc;
}
fclose(fp4);
printf("Enter a pattern to search: ");
scanf("%s", pat2);
ftime(&before);
HorspoolMatching(buf, pat2);
ftime(&after);
int diffTime4 = (after.time - before.time)*1000 +
(after.millitm - before.millitm);
printf("Time it took: %d milliseconds.\n", diffTime4);
How do I get the length of the unsigned parameter without an error? I was advised to change to unsigned chars because my output is incorrect. Im trying to go through a test file to find matches using the horspool algorithm.
warning: passing 'unsigned char *' to parameter of type
'const char *' converts between pointers to integer types with different
sign [-Wpointer-sign]
n = strlen(T);
^
/usr/include/string.h:82:28: note: passing argument to parameter here
size_t strlen(const char *);
You could cast the unsigned char * to char * for strlen without ill effects. However, there is a far more pressing issue with your code.
Since the chars might be signed, P[m - 1 - k] == T[i - k] is incorrect: then P[m] would be signed and T[n] would be unsigned - the characters that have sign bit on wouldn't match (i.e. having unsigned value >= 128 on machine with CHAR_BIT 8). As the Horspool's algorithm uses the characters as index to arrays, it would be easiest to have both parameters as unsigned char[]. Even better: use a variable of type unsigned char * to represent them, while accepting char * as the argument:
void HorspoolMatching(char T[], char P[]) {
unsigned char *t = (unsigned char*)T;
unsigned char *p = (unsigned char*)P;
// and use t and p here on.
}
However, it is more common to write the matching so that it also accepts the length of the strings as parameters - often the length of the string is known beforehand so calculating it again within the function would be costly. Thus I'd recommend declaring the function as
char *HorspoolMatching(char T[], size_t T_len, char P[], size_t P_len);
void as the return value isn't useful either - I'd char * to the beginning of first match, or NULL if no match is found.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm trying to write a program that sorts numbers alphabetically in C.
Example Input:
2 35 6 8 4
Example Output:
8 4 6 35 2
Digits should be sorted corresponding to the words representing them, like:
1-one
2-two
3-three
4-four
5-five
6-six
7-seven
8-eight
9-nine
I'm able to sort single digits using switch cases. What is the best way to sort two or more digits?
One way, not most efficient would be: (Will give you just hints to solve the problem and not complete solution)
Use sprintf to convert numbers to string and store in an array of string. If you want to convert numbers to spelling, use this excellent tutorial. (pops on top of the google search)
Sort the string using qsort with below comparision function. Use a struct with number tagged with string if you want the number back.
Comparision function
static int
cmpstringp(const void *p1, const void *p2)
{
return strcmp(* (char * const *) p1, * (char * const *) p2);
}
[Optional] Extract the numbers back from the tag.
Any time you need to sort collections of related data by one value or another, you should be thinking struct. A structure holding each of the various values, (int value, char * of integer, and char * word for integer), can be sorted on any of them and provide you a way to correlate your values regardless of the sort order.
You basic challenge is to fill an array of struct with each of the values, sort on the char * word for integer, and then use it as you need. The various conversions are fairly straight forward, (1) convert the int to its char * equivalent (basically the opposite of itoa); and (2) use the lookup table to concatenate your word equivalents based on each digit in (1). (no need to leave a space between the word digits, unless you just feel like it)
Look over the following example. It is just one way to do what you are trying to do. Let me know if you have an questions:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum {MAXC = 32, MAXW = 64};
/* struct holding both integer and number strings */
typedef struct bs {
int v;
char buf[MAXC];
char str[MAXW];
} bs;
const char *numbers[] = { "zero", /* string lookup */
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine" };
char *l2str (long v, char *str, size_t *l);
static int cmpbsp (const void *p1, const void *p2);
int main (void) {
int array[] = {2, 35, 6, 8, 4};
int i, n = sizeof array/sizeof *array;
bs bufstr[n]; /* array of struct */
size_t len = 0;
memset (bufstr, 0, n * sizeof *bufstr); /* initialize to zero */
for (i = 0; i < n; i++) { /* for each in array */
bufstr[i].v = array[i]; /* fill integer val */
l2str (array[i], bufstr[i].buf, &len); /* convert to str */
char *p = bufstr[i].buf;
for (; *p; p++) /* concatenate number for each digit */
strcat (bufstr[i].str, numbers[*p - '0']);
}
for (i = 0; i < n; i++) /* print original sort order */
printf (" bufstr[%d] v : %2d buf : %2s str : %s\n",
i, bufstr[i].v, bufstr[i].buf, bufstr[i].str);
putchar ('\n');
qsort (bufstr, n, sizeof *bufstr, cmpbsp); /* qsort on str */
for (i = 0; i < n; i++) /* print integers alpha-sorted on numbers */
printf (" bufstr[%d] v : %2d buf : %2s str : %s\n",
i, bufstr[i].v, bufstr[i].buf, bufstr[i].str);
putchar ('\n');
return 0;
}
/** convert long to string reversing digits in place.
* base 10 conversion of long value 'v' to string 'str'
* with string length returned through 'l'. 'd' is a
* pointer to the first digit in 'str' used to reverse
* the order of the digits in 'str' in place.
*/
char *l2str (long v, char *str, size_t *l)
{
if (!str) return NULL;
char *d, *p;
char tmp;
/* initialize pointers & length */
d = p = str;
*l = 0;
/* handle negative */
if (v < 0) {
*p++ = '-';
v = -v;
d++;
}
/* convert to char, terminate */
while (v > 0) {
*p++ = (v % 10) + '0';
v /= 10;
}
*p = 0;
*l = (size_t)(p - str);
/* reverse digits in place */
while (--p > d) {
tmp = *p;
*p-- = *d;
*d++ = tmp;
}
return str;
}
/* simple struct compare based on str */
static int cmpbsp (const void *p1, const void *p2)
{
return strcmp (((bs *)p1)->str, ((bs *)p2)->str);
}
Output
The original order and then alpha-sorted order (based on one, two, ...) are shown below.
$ ./bin/alphasortintarray
bufstr[0] v : 2 buf : 2 str : two
bufstr[1] v : 35 buf : 35 str : threefive
bufstr[2] v : 6 buf : 6 str : six
bufstr[3] v : 8 buf : 8 str : eight
bufstr[4] v : 4 buf : 4 str : four
bufstr[0] v : 8 buf : 8 str : eight
bufstr[1] v : 4 buf : 4 str : four
bufstr[2] v : 6 buf : 6 str : six
bufstr[3] v : 35 buf : 35 str : threefive
bufstr[4] v : 2 buf : 2 str : two
note: as mentioned in the comment where you are provided a link to convert numbers to words, you can improve the conversion by adding teens, and tens powers (e.g. thirteen, thirty, etc..) with just a bit of additional effort.