Getting a value from a char array - c

I have written a function below to take a char array and manipulate its values (namely, convert the char to an int if it is a number). However, I have a question with how the char array is managed. When I look at input[i], it is the correct value (the value that was placed in the array. However, &input[i] gives a capital letter, and I don't know why it does that. For example, if I enter "11" and trace the variables, I might get the following result:
input[0] is 1
&input[0] is D
input[1] is 1
&input[1] is E
On to my code, if I try to use input[i], I get the error of "passing argument makes pointer from integer without cast". If I use &input[i], the code compiles but I get the wrong result. What's going on with this, and how do I access the value I'm trying to get?
Below is my code:
void myFunction(char *input) {
Queue* numberQueue = queue_new();
Queue* opQueue = queue_new();
int i = 0;
int j;
for (j = 0; j < strlen(input); j++) {
printf("input[%d] is %c\n", i, input[i]);
printf("&input[%d] is %c\n", i, &input[i]);
int number = (int)input[i];
/* queue_push_tail(queue, data) */
queue_push_tail(numQueue, number); /* ERROR */
/* rest of code omitted */
i++;
}
}

If I understand that you want to push each digit in the input character string into queue_push_tail, as an integer value then you want your loop to do something like this:
for (j = 0; j < strlen(input); j++) {
if ( input[j] >= '0' && input[j] <= '9')
{
number = input[j] - '0';
/* queue_push_tail(queue, data) */
queue_push_tail(numQueue, number); /* ERROR - FIXED*/
/* rest of code omitted */
}
}
Recall, ASCII characters are themselves unsigned integers. You simply need to adjust the value for each character by subtracting the value of ASCII '0'. If you need to collect all numbers from the string into a single number (e.g. ac7f9gh3 => 793) then simply store the values unadjusted in a temp string, and then call atoi (temp).

Related

I'm having a problem with sending a char pointer to a function and assigning a value to it in C

I am trying to register to the address I sent to the function in the code structure you see below. But the for loop itself adds something. It only does this on arrays of 11 elements. That is, if "Hasan Polat" comes, he adds it, but if "Hasann Polat" comes, he does not add it. Or anything other than any 11 element array.printf output is written next to it
void sezarSifreleme(char cumle[], int kaydirma, char *sifreliCumle) {
char alfabe[26] = {'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'};
int i,j, cumleUzunluk = strlen(cumle);
for(i=0; i < cumleUzunluk; i++) {
if(cumle[i]==' ') {
cumle[i] = ' ';
} else {
for(j=0;j < 26; j++){
if(cumle[i] == alfabe[j]){
j = j + kaydirma;
j = j % 26; // Sezar sifrelemede sona geldikten sonra basa donulur onu saglamak amacli 26'ya mod aliriz.
cumle[i] = alfabe[j];
break;
}
}
}
printf("**");
// Sonucu main fonk icerisine gondermek icin aldigimiz degisken adresine sifreledigimiz cumleyi atiyoruz
for(i=0; i < cumleUzunluk; i++) {
sifreliCumle[i] = cumle[i];
printf("%c", sifreliCumle[i]); // **mfxfs utqfy**
}
printf("**");
printf("??%s??", sifreliCumle); // ??mfxfs utqfy??
}
Taking into account these two outputs: one with the fixed number of characters cumleUzunluk in the for loop
printf("**");
// Sonucu main fonk icerisine gondermek icin aldigimiz degisken adresine sifreledigimiz cumleyi atiyoruz
for(i=0; i < cumleUzunluk; i++) {
sifreliCumle[i] = cumle[i];
printf("%c", sifreliCumle[i]); // **mfxfs utqfy**
}
printf("**");
and other with using the conversion specifier s
printf("??%s??", sifreliCumle); // ??mfxfs utqfy??
it means that at least the pointer sifreliCumle does not point to a string.
You could rewrite this call of printf the following way
printf("??%.*s??", cumleUzunluk, sifreliCumle);
or append the zero character '\0' provided that the array pointed to by the pointer sifreliCumle have a space to store the zero character '\0' as for example
sifreliCumle[cumleUzunluk] = '\0';
printf("??%s??", sifreliCumle);
I don't know what your code is doing, but I see that you have this routine:
void sezarSifreleme(char cumle[], int kaydirma, char *sifreliCumle)
and it is defined as having a void return. I see you maninpulating the pointers inside the routine, but none are remained modified outside the routine unless you either use pointer to pointers are you return the pointer in function signature.
char * sezarSifreleme(char cumle[], int kaydirma, char *sifreliCumle)
...
return sifreliCumle;
What is that anyway? Signed Integer, free, li cumulative, little endian?

C programming problem pointers and arrays 2d

Q2: Implelment the follwoing function ArrPrintMatrix(char *(p)[7]) which prints the content of the matrix[m][7] ={"SHAHBAZ","AYAZ"} in to 3x3 Matrix
Sample Output
S H A
H B A
Z A Y ..
My question is : here is code only problem i am getting is a space after one name is completed..how to remove that space . I have this question in my assignments , that have to be submitted on sunday (11-11-18)..
My code is:
#include<stdio.h>
int main()
{
void ArrPrintMatrix(char *p);//function declaration
char matrix[2][8] ={"SHAHBAZ","AYAZ"};//2d array initiliation
ArrPrintMatrix(&matrix[0][0]);//calling function with base address
}
void ArrPrintMatrix(char *p)
{
int i;
for(i=0;i<16;i++)
{
if(i>=9)//since 3 by 3 matrix is required
break;
if(i==3||i==6||i==9)//changing line since 3 by 3 matrix is needed
printf("\n");
printf("%c ",*(p+i));//prininting chracters
}
}
You should use char (*p)[8] not char* p
The following code could wrok:
#include<stdio.h>
int main()
{
void ArrPrintMatrix(char (*p)[8]);//function declaration
char matrix[2][8] ={"SHAHBAZ","AYAZ"};//2d array initiliation
ArrPrintMatrix(matrix);//calling function with base address
}
void ArrPrintMatrix(char (*p)[8])
{
// i will point to one of the strings in the set of strings
// j will point into the string we are inspecting
// k will count how many characters we have printed
int i = 0, j = 0, k = 0;
// we only need to print the first 9 printable characters we find
while (k != 9)
{
// if we have reached the end of an input string (the null-terminator),
// then move on to the next element in the array, and reset
// the string pointer to the beginning of the new string
if (p[i][j] == '\0') {
++i;
j = 0;
}
// print the character we are now pointing at,
// and increment the string pointer
printf("%c ", p[i][j++]);
// keep count of how many characters we have printed
++k;
// if k is divisible by 3, start a new row
if(k%3 == 0)
printf("\n");
}
}
As a follow-on to my other answer, if you do use my logic to skip over the '\0' that terminates the strings, you will need to use a different variable to keep track of how many characters you've actually printed, and just let i keep track of where you are in the input string(s). Like so:
#include<stdio.h>
int main()
{
void ArrPrintMatrix(char *p);//function declaration
char matrix[2][8] ={"SHAHBAZ","AYAZ"};//2d array initiliation
ArrPrintMatrix(&matrix[0][0]);//calling function with base address
}
void ArrPrintMatrix(char *p)
{
int i, j;
for(i=0, j=0;i<16;i++)
{
if(j>=9)//since 3 by 3 matrix is required
break;
if(j==3||j==6||j==9)//changing line since 3 by 3 matrix is needed
printf("\n");
if (*(p+i)==0) continue; //don't try to print the trailing '\0'
printf("%c ",*(p+i));//prininting chracters
j++; //increment counter of characters actually printed
}
}
Output:
S H A
H B A
Z A Y
Note the use of the j variable, and how it is incremented with j++ only after actually printing a character.
What you are missing is that there is a trailing '\0' at the end of SHAHBAZ, which you are also "printing", but because '\0' does not have a character representation, you are seeing what looks like an 'extra' space.
Here is the smallest change I can think of to address this exact problem; add:
if (*(p+i)==0) continue; //don't try to print the trailing '\0'
just above your existing line:
printf("%c ",*(p+i));//prininting chracters
Output:
S H A
H B A
Z A
There are other things I would do differently than how you are doing them, but this addresses your exact question, using your coding style.

How to check if an array of characters is a valid integer >= 1 in c?

I don't know the size of the array and using isdigit(array[i]) for every element i < sizeof(array) doesn't seem to work correctly.
I am trying to:
Check that every char is a digit.
Convert the string to int.
Check that it is > 0
int all_digits(char *string){
short i;
for(i=0; i < sizeof(string); i++){
if (!isdigit(string[i])){
//Non-digit found.
return 1;
}
}
//All of them are digits.
return 0;
}
The first part is the one that I can't get.
int n = strlen(string);
for(i=0; i < n; i++)
sizeof(pointer) is not same as sizeof(array)
You need to pass a valid string which is a null terminated string else strlen() might crash.
Edits:
Alternatively you can have
for(i=0; string[i] != '\0'; i++)
In this case you cannot get the correct length using the sizeof function.
sizeof function will give you the size of the given data type. You can use the
strlen function.
While using the strlen you have to manage the following,
Consider in your string in last there is no null value you didn't get the correct value of the string length. For this you have to send the size of that array as a another parameter or you have to place the null value in the last value of the a string.
Then you can get that easily.
In your code, string is of type char *. sizeof(string) will give you the size of a char *, not the array.
You need to pass the size of the array explicitly, using another paramter to all_digits() function and use that value in for loop condition checking.
Maybe something like this
int all_digits(char *string, int size){
short i;
for(i=0; i < size; i++){
if (!isdigit(string[i])){
//Non-digit found.
return 1;
}
}
//All of them are digits.
return 0;
}
Note: Specifically in case of a char *, a better, smaller and cleaner approach to this can be achieved using strlen() [assuming proper aguments passed], which will give you the length of the supplied string.
Simply iterate along the string, testing every character:
int all_digits(char *string){
if( *string == 0) // empty string - wrong
return 1;
for( ; *string != 0; string++) // scan the string till its end (a zero byte (char)0)
if (!isdigit(*string)) // test for a digit
return 1; // not a digit - return
return 0; // all characters are digits
}
However that only tests if the string consists of digits and does not make you any closer to determining its numerical value...

Array manipulation in C

I am like 3 weeks new at writing c code, so I am a newbie just trying some examples from a Harvard course video hosted online. I am trying to write some code that will encrypt a file based on the keyword.
The point is each letter of the alphabet will be assigned a numerical value from 0 to 25, so 'A' and 'a' will be 0, and likewise 'z' and 'Z' will be 25. If the keyword is 'abc' for example, I need to be able to convert it to its numerical form which is '012'. The approach I am trying to take (having learned nothing yet about many c functions) is to assign the alphabet list in an array. I think in the lecture he hinted at a multidimensional array but not sure how to implement that. The problem is, if the alphabet is stored as an array then the letters will be the actual values of the array and I'd need to know how to search an array based on the value, which I don't know how to do (so far I've just been returning values based on the index). I'd like some pseudo code help so I can figure this out. Thanks
In C, a char is an 8-bit integer, so, assuming your letters are in order, you can actually use the char value to get the index by using the first letter (a) as an offset:
char offset = 'a';
char value = 'b';
int index = value - offset; /* index = 1 */
This is hard to answer, not knowing what you've learned so far, but here's a hint to what I would do: the chars representing letters are bytes representing their ASCII values, and occur sequentially, from a to z and A to Z though they don't start at zero. You can cast them to ints and get the ascii values out.
Here's the pseudo code for how I'd write it:
Cast the character to a number
IF it's between the ascii values of A and Z, subtract it from A
ELSE Subtract it from the ASCII value of a or A
Output the result.
For what it's worth, I don't see an obvious solution to the problem that involves multidimensional arrays.
char '0' is the value 48
char 'A' is the value 65
char 'a' is the value 97
You said you want to learn how to search in the array:
char foo[26]; //your character array
...
...
//here is initialization of the array
for(int biz=0;biz<26;biz++)
{
foo[biz]=65+biz; // capital alphabet
}
...
...
//here is searching 1 by 1 iteration(low-yield)
char baz=67; //means we will find 'C'
for(int bar=0;bar<26;bar++)
{
if(foo[bar]==baz) {printf("we found C at the index: %i ",bar);break;}
}
//since this is a soted-array, you can use more-yield search algortihms.
Binary search algortihm(you may use on later chapters):
http://en.wikipedia.org/wiki/Binary_search_algorithm
The use of a multidimensional array is to store both the lower case and upper case alphabets in an array so that they can be mapped. An efficient way is using their ASCII code, but since you are a beginner, I guess this example will introduce you to handle for loops and multidimensional arrays, which I think is the plan of the instructor as well.
Let us first set up the array for the alphabets. We will have two rows with 26 alphabets in each row:
alphabetsEnglish[26][2] = {{'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'},
{'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'}};
Now we can map elements of both cases.
int main()
{
int c,i,j;
char word[10];
printf("Enter a word:");
scanf("%s",word);
c=strlen(word);
printf("Your word has %d letters ", c);
for (i = 0; i < c; i++) //loop for the length of your word
{
for (j = 0; j <= 25; j++) //second loop to go through your alphabet list
{
if (word[i] == alphabetsEnglish[0][j] || word[i] == alphabetsEnglish[1][j]) //check for both cases of your alphabet
{
printf("Your alphabet %c translates to %d: ", word[i], j);
}
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *conv(char* str){
static const char* table = "abcdefghijklmnopqrstuvwxyz";
int size, *ret, *p;
if(NULL==str || *str == '\0') return NULL;
size = strlen(str);
ret=p=(int*)malloc(size*sizeof(int));
while(*str){
char *pos;
pos=strchr(table, tolower(*str++));
*p++ = pos == NULL ? -1 : pos - table;
}
return ret;
}
int main(void){
char *word = "abc";
int i, size = strlen(word), *result;
result = conv(word);
for(i=0;i<size;++i){
printf("%d ", result[i]);//0 1 2
}
free(result);
return 0;
}

Concat LPSTR in C

Trying to use as basic C as I can to build a list of numbers from 1-52 in a random order (deck of cards). Everything works, but all of my attempts to concat the strings and get a result end in failure. Any suggestions? NOTE: This is not homework it's something I'm using to create a game.
// Locals
char result[200] = ""; // Result
int card[52]; // Array of cards
srand(time(0)); // Initialize seed "randomly"
// Build
for (int i=0; i<52; i++) {
card[i] = i; // fill the array in order
}
// Shuffle cards
for (int i=0; i<(52-1); i++) {
int r = i + (rand() % (52-i));
int temp = card[i]; card[i] = card[r]; card[r] = temp;
}
// Build result
for (int c=0; c<52; c++) {
// Build
sprintf(result, "%s%d", result, card[c]);
// Comma?
if ( c < 51 )
{
sprintf(result, "%s%s", result, ",");
}
}
My end result is always garbled text. Thanks for the help.
You keep writing to the same position of "result".
sprintf is not going to do the appending for you.
You may consider, after each sprintf, get the return value (which is the number of char written), and increment the pointer to result buffer. i.e. something like:
(psuedo code):
char result[200];
char * outputPtr = result;
for (int c=0; c<52; c++) {
// Build
int n = sprintf(outputPtr, "%d%s", card[c], (c<51 ? "," : ""));
outputPtr += n;
}
Are we writing C++ or C? In C++, concat-ing a string is just:
string_out = string_a + string_b
…since you'd be using std::string.
Furthermore, if this is C++, the STL has a std::shuffle function.
If this is C, note that all your sprintfs aren't concatenating strings, they're just overwriting the old value.
I think, if memory serves, that sprintf will always write into the buffer starting at byte 0. This means that you would be writing the first couple of bytes over and over again with a number, then a comma, then a number. Check if your first bytes are ",[0-9]" - if so, that's your issue.
This would add a comma between each number in the result string:
// Get a pointer to the result string
char* ptr = &result[0];
for (int c = 0; c < 52; c++) {
// Add each cards number and increment the pointer to next position
ptr += sprintf(ptr, "%d", card[c]);
// Add a separator between each number
if (c < 51) {
*ptr++ = ',';
}
}
// Make sure the result string is null-terminated
*ptr = 0;

Resources