Removing the leading zeroes of a number stored in string - c

struct number {char digits[11];};
The following method removes leading zeroes from (*a).digits
void remove_zero(struct number *a);
Example: (*a).digits 000013204 ---> 13204
My approach is to define a variable b equals to (*a).digits, start seaching for the first non-zero number in b, then replace (*a).digits with the rest of b. However, I am having trouble implementing the code
void remove_zero(struct number *a) {
char b = (*a).digits;
while (b){ // <--- (b) indicates that it hasnt reached the terminator,right?
if (b != '0')
{ //<-- here is where to replace (*a).digits with the rest of b, but how to?
break;
}
}
}

So you have an array that contains e.g.
+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 1 | 3 | 2 | 0 | 4 | \0| |
+---+---+---+---+---+---+---+---+---+---+---+
And you want it to contain
+---+---+---+---+---+---+---+---+---+---+---+
| 1 | 3 | 2 | 0 | 4 | \0| | | | | |
+---+---+---+---+---+---+---+---+---+---+---+
From the "images" above, it should be pretty clear that this can be done using a simple movement of the data.
So one solution is to find the first non-zero character, and move from that to the beginning of the array.

In general it's clearer to deference a pointer to a struct and access its attributes using the -> operator, e.g. rather than
char b = (*a).digits;
do this
char *b = a->digits;
Note that digits is an array of chars, so b needs to be an array of chars, or a pointer to a char as shown here.
So:
void remove_zero(struct number *a)
{
char *b = a->digits;
char *end = a->digits + sizeof a->digits - 1;
while (b < end && *b == '0')
b++;
if (b != a->digits)
{
size_t n = end - b;
memmove(a->digits, b, n);
a->digits[n] = '\0';
}
}

Related

How to store words from a text file into an array?

I'm trying to read a text file called "olaola.dict", some sort of a dictionary, that currently holds 10 words each with 5 letters and store the words into an array of strings. I'm using a char** pointer that points to an array of pointers in which each pointer points to a word from the dictionary.
So far, I've developed this code. It is printing the last 7 words correctly, but not the first three. The code is the following:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ROW 10 /* 10 words */
#define COL 6 /* 5 letters in each word + Null terminator*/
int main(void) {
int i, j;
FILE *fp = NULL;
char **ptr = NULL;
ptr = (char**)malloc(ROW * sizeof(char*));
fp = fopen("olaola.dict","r");
for (i=0 ; i < 15; i++) {
if ((ptr[i] = malloc(sizeof(char) * COL)) == NULL) {
printf("unable to allocate memory \n");
return -1;
}
fscanf(fp, "%s", ptr[i]);
}
for(i = 0; i < ROW; i++){
printf("Word %d:%s\n", i+1,ptr[i]);
}
for (i=0 ; i < ROW; i++)
free(ptr[i]);
free(ptr);
fclose(fp);
return 0;
}
/*
ptr[] 0 1 2 3 4 5 6
+--------+ +---+---+---+---+---+---+---+
| --|------->| w | o | r | d | 0 | 0 |\0 |
+--------+ +---+---+---+---+---+---+---+
| --|------->| w | o | r | d | 0 | 1 |\0 |
+--------+ +---+---+---+---+---+---+---+
| --|------->| w | o | r | d | 0 | 2 |\0 |
+--------+ +---+---+---+---+---+---+---+
| --|------->| w | o | r | d | 0 | 3 |\0 |
+--------+ +---+---+---+---+---+---+---+
| --|------->| w | o | r | d | 0 | 4 |\0 |
+--------+ +---+---+---+---+---+---+---+
*/
The output is:
Word 1:[p:�
Word 2:0[p:�
Word 3:P[p:�
Word 4:Carlo
Word 5:Andre
Word 6:MESSI
Word 7:Arroz
Word 8:Doces
Word 9:Carro
Word 10:Tevez
Here is also the text file olaola.dict
lista
Sabes ontem Carlo
Andre
MESSI
Arroz Doces Carro Tevez
As you can see, there is no specific position for the words to be.
What would be the correct way to solve this problem?
(In another note, would it be wiser and more efficient to use a 2D array, even though the dictionary can have like 5k words ?)
I noticed that the first for loop goes from zero to 14 instead of from zero to 9. This means that the code writes beyond the boundaries of the array. I assume that this writes to the memory being allocated for the first 3 words and this is the reason why you see the wrong values for these words. Correct the for loop and see if this solves the issue.
you problem is in this line
for (i=0 ; i < 15; i++) {
it's supposed to be:
for (i=0 ; i < ROW; i++)
because you should allocate till ptr[9], but you are allocating till ptr[14] which will produce undefined behavior as the size of the array = 10

How to add items to array in a function using pointers?

I am trying to write this function that takes an array input and assigns random numbers between 1-52 to the array. Then prints back the numbers. I get an error message on the 4th line that says expression is not assignable. Is my use of pointers incorrect or is it not possible to add content to array with pointers?
void shuffleDeck(int *deck[]) {
int i;
for(i=0;i<=52;i++)
rand()%53 = deck[i]; // I get an error message on this line
}
int main() {
srand(time(NULL));
int deck[2000];
shuffleDeck(deck);
int i;
for(i=0;i<=52;i++){
printf("%d", deck[i]);
}
return 0;
}
Assigment direction is from right to left
So in this expression
deck[i] = rand()%52 + 1;
First is called function rand()
Then the result of function %52
Then 1 is added
And finnally its assigned to deck[i]
Array (what you have in main) is
0 1 2 3 4
+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+
^-------------------------- arr[0]
While Array of pointers (what your function expects) is
0 1 2 3 4
+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0
+---+---+---+---+---+
------^
| +---+---+---+---+---+
| | 0 | 0 | 0 | 0 | 0 | 1
| +---+---+---+---+---+
| +---+---+---+---+---+
| | 0 | 0 | 0 | 0 | 0 | 2
| +---+---+---+---+---+
|
----------------------------- arr[0][0]
When array is passed to function, then arr[] and *arr are the same. But only as function arguments!
%53 returns 0-52,so if you need 1-52, use %52 + 1 (0-51 + 1 = 1-52)
If you cant solve it, here is code with fixed bugs.
void shuffleDeck(int deck[]) {
int i;
for(i=0;i<=52;i++)
deck[i] = rand()%52 + 1;
}
int main() {
srand(time(NULL));
int deck[2000];
shuffleDeck(deck);
int i;
for(i=0;i<=52;i++){
printf("%d", deck[i]);
}
return 0;
}

Why the first prime number always becoming 1 instead of 2

Here i am trying to implement sieve of erastosthene in c.The program works fine except one major problem.I manually set the first prime number to be of value 2.But at the end when i loop through all the prime numbers array and print them ,the first value becomes 1 instead of 2.Can't figure out why this problem arises.Any help would be much appreciated.
#include<stdio.h>
#include<math.h>
int main(){
int n = 64;
int i,j,limit=sqrt(n)+2,nPrime=0;
int prime[50]={0},mark[64]={0};
mark[1]=1;
prime[nPrime++] = 2;
printf("%d\n",prime[0]); // initialized to 2
for(i=4;i<=n;i=i+2){
mark[i] = 1;
}
for(i=3;i<=n;i=i+2){
if(!mark[i]){
prime[nPrime++] = i;
if(i<=limit){
for(j=i*i;j<=n;j=j+i*2){
mark[j]=1;
}
}
}
}
int k;
int size = sizeof(prime)/sizeof(prime[0]);
printf("%d\n",prime[0]); // changed to 1;
for(k=0;k<size && prime[k]!=0;k++){
printf("%d ",prime[k]);
}
}
The problem is in this loop:
for(i=4;i<=n;i=i+2) {
mark[i] = 1;
}
The condition should be i < n, because with <= it will take the value 64, and that would be out of bounds.
When you set mark[64] = 1 you are modifying memory that does not belong to the mark array, in this case it turn out to be the first element of the prime array. If you test out other indexes, you could end up getting a segfault.
If you set manually mark[64] = 56, you will see that prime[0] == 56
Because local variable are declared on stack, in your case the variable mark[64] which is an array of 64 integer (64 * 4 = 256 bytes) occupies the first 256 bytes of the stack then the array prime (50 * 4 = 200 bytes) occupies the next 200 bytes as shown below:
Stack
|-----------|
| other |
| variables |
| |
prime[49]->|-----------| addr = 0x000001C8
| |
| prime |
|(200 bytes)|
prime[0]->| |
mark[63]->|-----------| addr = 0x00000100
| |
| |
| mark |
|(256 bytes)|
| |
mark[0]->|-----------| addr = 0x00000000
When you write mark[64] = 1, you are actually writing the four bytes of prime[0] = 1.

What does "char *t = s + len" mean?

I'm going through a programming book and I'm wondering what a line of code does. There are no comments in the book or explanations about what it's supposed to do.
Below is a function that takes a character array and prints it backwards.
void print_reverse (char *s)
{
size_t len = strlen(s);
char *t = s + len -1; // I don't understand what this line is doing
while (t >= s) {
printf("%c", *t);
t = t - 1;
}
puts("");
}
Let's say s is the string "PaxDiablo", stored in memory at location 1 thus:
s
|
V
+---+---+---+---+---+---+---+---+---+----+
| P | a | x | D | i | a | b | l | o | \0 |
+---+---+---+---+---+---+---+---+---+----+
Address: 1 2 3 4 5 6 7 8 9 10
The expression t = s + len - 1 (where len is 9 in this case) sets t to eight characters past s.
s t
| |
V V
+---+---+---+---+---+---+---+---+---+----+
| P | a | x | D | i | a | b | l | o | \0 |
+---+---+---+---+---+---+---+---+---+----+
Address: 1 2 3 4 5 6 7 8 9 10
In other words, it gives you the address of the last character in the string.
The rest of the code then iterates over the string in a backwards direction, by decrementing t until it passes s.
Technically, this is undefined behaviour since you're only every supposed to compare pointers where they point to the same array on one character beyond (here we are comparing t where it's one character before the array), but you'd struggle to find a system on which this didn't work.
As Potatoswatter (I absolutely love some of the names people choose here on SO) points out in a comment, you can avoid that comparison by using the do {} while construct rather than while {}:
#include <stdio.h>
#include <string.h>
void printReverse (char *str) {
size_t len = strlen (str);
if (len != 0) {
char *pStr = str + len;
do {
putchar (*(--pStr));
} while (pStr > str);
}
putchar ('\n');
}
Let's say s points to the string "Hello". In memory, it looks like:
s --> [ H | e | l | l | o | \0 ]
Now, char *t declares a new pointer variable to a char value, that is initialized with s + len - 1, which is:
s ------ ------- s + 5 // (len is 5 since strlen("Hello") is 5)
| |
[ H | e | l | l | o | \0 ]
|
------------ finally, t = s + len - 1

Rotate multi-dimension pointer

If I have a multidimension pointer representation of a grid like so
char **p;
int w; // width (i.e. number of columns)
int h; // height (i.e. number of rows)
How do I go about creating a copy that is rotated by 90 degrees clockwise for NxM grid?
I've tried mallocing the height as the new width, and width as new height then transposing the values. Then I was going to finish by reversing the values of the row but I haven't managed to do this.
Actual transposition is moderately painful: you have to move every element from "where it is now" to "where it should be in the transposition". If you really do have a pointer p pointing to the first of M pointers, and each of those M pointers points to the first of N chars (used as if it's an array of size M of arrays of size N of chars):
+---+ +---+---+---+---+
p ---> | * | ----> | a | b | c | d |
+---+ +---+---+---+---+
| * | --
+---+ \ +---+---+---+---+
| * | -----------> | i | j | k | l |
+---+ \ +---+---+---+---+
\
\ +---+---+---+---+
--> | e | f | g | h |
+---+---+---+---+
then you need a new pointer (which I will call q) pointing to the first of N pointers, each of which points to the first of M chars (note: this is a different transposition than you asked for):
+---+ +---+---+---+
q ---> | * | -----> | a | e | i |
+---+ +---+---+---+
| * | --
+---+ \
| * |etc \ +---+---+---+
+---+ ---> | b | f | j |
| * |etc +---+---+---+
+---+
However, if you can live with relatively annoying subscript-writing and any cache miss effects on your runtime, you can simply access p[i][j] as p[j][i] or p[N-1-j][i], etc., to "pretend" that things are transposed. This might be easiest with some macros:
#define ORIENTATION_A(p, M, N, i, j) ((p)[i][j])
#define ORIENTATION_B(p, M, N, i, j) ((p)[(N)-1-(j)][i])
/* etc */
(note: none of the above is tested).
When using type char **, since the fixed-size solution is already posted I thought I would chime in with a dynamic, \0 terminated solution that works with various-sized arrays. If it is possible to terminate the arrays h and w can be omitted. This function can figure out the h and w. Of course it may be changed to support h and w, but the powers that be would rather I get back to work funding their empire rather than providing free help.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
/* rotate_array
w h
**p _______ **q ___
|A B C D|\0 ===> |E A|\0
h |E F G H|\0 ==> |F B|\0 w
NULL----- |G C|\0
|H D|\0
NULL-
*/
char **rotate_array(char **p) {
int w,h,hh;
char **q;
for (w=0;p[0][w];w++);
for (hh=0;p[hh];hh++);
if (!(q = malloc(w * sizeof q))) {
perror ("malloc");
exit (1);
} fprintf (stderr,"made it\n");
for (w=0;p[0][w];w++) {
if (!(q[w] = malloc(hh))) {
perror ("malloc");
exit (1);
} for (h=0;h<hh;h++) {
q[w][hh-h-1] = p[h][w];
} q[w][h]='\0';
} q[w]=NULL;
return q;
} void free_array(char **p) {
int h;
for (h=0;p[h];h++) {
free (p[h]);
} free (p);
}
// main
int main (int argc, char **argv) {
int h;
char *p[3]={"ABCD","EFGH",NULL};
char **q;
for (h=0;p[h];h++) {
printf ("%s\n",p[h]);
} printf ("\n");
q = rotate_array (p);
for (h=0;q[h];h++) {
printf ("%s\n",q[h]);
} free_array (q);
return 0;
}

Resources