I want to know why this result is output - c

source code
/***************************************************
* Copyright: 2023, 黄子涵.
* File name: huangzihan_c_program_142
* Description: 改变指针的值
* Author: 黄子涵
* Version: V1.0.0
* Date: 2023-01-08
* ****************************************************/
#include <stdio.h>
char huangzihan[10];
char huangchunqin[12];
char chenlanying[12];
char shejiazi[8];
void name_input();
void name_output();
void name_output_n();
void name_input()
{
int i;
printf("*********************************\n");
printf(" 给字符数组输入对应的名字 \n");
printf("*********************************\n");
printf("请输入黄子涵的小写拼音:");
for (i = 0; i < 10; i++)
{
scanf("%c", &huangzihan[i]);
if (huangzihan[i] == 10)
{
huangzihan[i] = '\0';
break;
}
}
getchar();
printf("请输入黄春钦的小写拼音:");
for (i = 0; i < 12; i++)
{
scanf("%c", &huangchunqin[i]);
if (huangchunqin[i] == 10)
{
huangchunqin[i] = '\0';
break;
}
}
getchar();
printf("请输入陈兰英的小写拼音:");
for (i = 0; i < 11; i++)
{
scanf("%c", &chenlanying[i]);
if (chenlanying[i] == 10)
{
chenlanying[i] = '\0';
break;
}
}
getchar();
printf("请输入佘佳梓的小写拼音:");
for (i = 0; i < 8; i++)
{
scanf("%c", &shejiazi[i]);
if (shejiazi[i] == 10)
{
shejiazi[i] = '\0';
break;
}
}
printf("\n");
}
void name_output()
{
char *p1,*p2,*p3,*p4;
printf("*********************************\n");
printf(" 将字符数组对应的名字输出 \n");
printf("*********************************\n");
printf("输出huangzihan:");
p1 = huangzihan;
printf("%s", p1);
printf("\n");
printf("输出huangchunqin:");
p2 = huangchunqin;
printf("%s", p2);
printf("\n");
printf("输出chenlanying:");
p3 = chenlanying;
printf("%s", p3);
printf("\n");
printf("输出shejiazi:");
p4 = shejiazi;
printf("%s", p4);
printf("\n");
}
void name_output_n()
{
int i;
char *p;
printf("\n");
printf("*********************************\n");
printf(" 改变指针的值 \n");
printf("*********************************\n");
printf("你要从第几个字符输出huangzihan(共10个字符)?");
scanf("%d", &i);
p = huangzihan + i - 1;
printf("这是你要输出的字符串:%s", p);
printf("\n");
printf("你要从第几个字符输出huangchunqin(共12个字符)?");
scanf("%d", &i);
p = huangchunqin + i - 1;
printf("这是你要输出的字符串:%s", p);
printf("\n");
printf("你要从第几个输出chenlanying(共11个字符)?");
scanf("%d", &i);
p = chenlanying + i - 1;
printf("这是你要输出的字符串:%s", p);
printf("\n");
printf("你要从第几个输出shejiazi(共8个字符)?");
scanf("%d", &i);
p = shejiazi + i - 1;
printf("这是你要输出的字符串:%s", p);
printf("\n");
}
int main()
{
extern char huangzihan[10];
extern char huangchunqin[12];
extern char chenlanying[12];
extern char shejiazi[8];
name_input();
name_output();
name_output_n();
return 0;
}
At first, I thought it was the problem of not adding the end tag of the string, but I added the end tag of the string and found it didn't work.Add code as follows:
if (shejiazi[i] == 10) {
shejiazi[i] = '\0';
break;
}
I want to output results
输出huangzihan:huangzihan
输出huangchunqin:huangchunqin
输出chenlanying:chenlanying
输出shejiazi:shejiazi
Actual output results
I want to know why this happens. If you know, please tell me. Thank you very much。

If the input string has exactly the maximum number of characters, the target array is not null terminated, causing printf("...%s", ...) to have undefined behavior. If your case it seems the arrays huangchunqin and chenlanying are adjacent in memory, so printf("%s",p2); outputs the contents of huangchunqin until it finds a null terminator, which does not occur before the end of chenlanying.
You should make the arrays one byte longer and use a function to read these strings:
/* Author: 查理戈登 */
/* Description: 程序的修改版本 */
#include <stdio.h>
char huangzihan[11];
char huangchunqin[13];
char chenlanying[13];
char shejiazi[9];
// read a string into a char array of a given length,
// return EOF if no input at end of file, 1 if truncated, 0 otherwise
int input_string(const char *prompt, char *dest, size_t size) {
size_t i = 0;
int c;
int result = 0;
printf("%s: ", prompt);
while ((c = getchar()) != EOF && c != '\n') {
if (i + 1 < size) {
dest[i++] = c;
} else {
result = 1;
}
}
dest[i] = '\0';
if (i == 0 && c == EOF)
result = EOF;
return result;
}
void name_input(void) {
printf("*********************************\n");
printf(" 给字符数组输入对应的名字 \n");
printf("*********************************\n");
// Qǐng shūrù shéjiāzǐ de xiǎoxiě pīnyīn
input_string("请输入黄子涵的小写拼音", huangzihan, sizeof huangzihan);
input_string("请输入黄春钦的小写拼音", huangchunqin, sizeof huangchunqin);
input_string("请输入陈兰英的小写拼音", chenlanying, sizeof chenlanying);
input_string("请输入佘佳梓的小写拼音", shejiazi, sizeof shejiazi);
printf("\n");
}

In name_input() you don't terminate your strings correctly as the last iteration is i=9:
for(i=0;i<10;i++) {
scanf("%c",&huangzihan[i]);
if(huangzihan[i]==10)
{
huangzihan[i]='\0';
break;
}
}
Instead you could do:
int i = 0;
for(; i < sizeof huangzihan - 1; i++) {
scanf("%c", &huangzihan[i]);
}
huangzihan[i] = '\0';
I don't know if your letters entered fit into the char if not you will get some weird corruption.
You can also just read a string with:
#define huangzihan_len 9
#define str(s) str2(s)
#define str2(s) #s
char huangzihan[huangzihan_len+1];
//...
scanf("%" str(huangzihan_len) "s", huangzihan);
After reading a string you do getchar() presumably to get rid of the newline. You can change the format string with an initial space to do that automatically " %c", or make a flush function that discards all data till you hit a new line:
void flush() {
for(;;) {
int ch = getchar();
if(ch == EOF || ch == '\n') return;
}
}
Your code is repetitive so consider using an array to hold your strings, as they are different length perhaps an array of string pointers char *str[4]?

Related

Trying to make QuizMaker in C, but some steps are ignored with !X

Basically I'm trying to make QuizMaker by asking user how many questions they want, then make a string of an array. I'm new to C, so I might be missing some little details. Please look at the screenshot of console which I included.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 4096
int input(char *str, int n);
int main() {
int a, i, length = 0;
printf("How many questions do you want?\n");
scanf("%d", &a);
char *strarr[a];
char buffer[BUFFER_SIZE]; //string holder
while (getchar() != '\n'); //in case there is \n, flush it
for(i = 0; i < a; i++) {
printf("Question number #%d:\n", i + 1);
length = input(buffer, BUFFER_SIZE);
//input method returns number of chars we've entered
strarr[i] = malloc((length) * sizeof(char));
//allocating memory for each pointers to array of chars
strcpy(strarr[i], buffer);
//copy the string you've just created to an array of strings
}
//printing results
printf("_____________\n");
for(i = 0; i < a; i++) {
printf("%s\n", strarr[i]);
}
return 0;
}
int input(char *str, int n) {
int ch, i = 0;
while ((ch = getchar()) != '\n') {
if (i < n)
str[i++] = ch;
str[i] = '\0';
}
return i;
}
There are some problems in the code:
the test if (i < n) is not strict enough: you should stop storing characters to the destination array before it is full to save space for the null terminator.
you must allocate one extra byte for the null terminator: malloc((length + 1) * sizeof(char)) or just malloc(length + 1) as sizeof(char) is 1 by definition.
you should test for EOF in addition to '\n' in the reading loops.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 4096
int input(char *str, int n);
int main() {
int a, c, i, length = 0;
printf("How many questions do you want?\n");
if (scanf("%d", &a) != 1 || a <= 0) {
fprintf(stderr, "invalid input\n");
return 1;
}
char *strarr[a];
char buffer[BUFFER_SIZE]; //string holder
// flush the rest of the input line
while ((c = getchar()) != EOF && c != '\n')
continue;
for (i = 0; i < a; i++) {
printf("Question number #%d:\n", i + 1);
//input method returns number of chars we've entered
length = input(buffer, BUFFER_SIZE);
//allocating memory for each pointers to array of chars
strarr[i] = malloc((length + 1) * sizeof(char));
if (strarr[i] == NULL) {
fprintf(stderr, "allocation error\n");
a = i;
break;
}
//copy the string you've just created to an array of strings
strcpy(strarr[i], buffer);
}
//printing results
printf("_____________\n");
for (i = 0; i < a; i++) {
printf("%s\n", strarr[i]);
}
return 0;
}
int input(char *str, int n) {
int ch, i = 0;
while ((ch = getchar()) != EOF && ch != '\n') {
if (i + 1 < n)
str[i++] = ch;
}
if (i < n)
str[i] = '\0';
return i;
}
Also note that you can use strdup() to allocate and copy the string in a single call:
for (i = 0; i < a; i++) {
printf("Question number #%d:\n", i + 1);
input(buffer, BUFFER_SIZE);
/* allocate a copy of the string */
strarr[i] = strdup(buffer);
if (strarr[i] == NULL) {
fprintf(stderr, "allocation error\n");
a = i;
break;
}
}

Why on while(getchar()!=EOF) it iterates extra time?

I'm trying to count chars from input, and I noticed that while(getchar()!=EOF) produces an extra count, Is it because it counts the null-terminated from input?
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define LINE 5
#define MEM_SIZE 10
char *getInput(int *counter);
void printInput(char *input);
int main() {
char *mainInput;
int counter = 0;
printf("Please enter your input:\n");
mainInput = getInput(&counter);
if (mainInput == NULL) {
return 1;
}
printf("\n\n\nOutput:\n%s\n", mainInput);
printf("number of chars: %d\n", counter);
printInput(mainInput);
free(mainInput);
return 0;
}
char *getInput(int *counter) {
char *p = (char *)malloc(MEM_SIZE * sizeof(char));
char *q = p; /* backup pointer, if realloc fails to allocate, function will return last address values stored */
int c;
int temp_counter = 0;
long current = 0, last = MEM_SIZE - 1;
while ((c = getchar()) != EOF) {
if (current >= last) {
q = p;
p = (char *)realloc(q, last + (MEM_SIZE * sizeof(char)));
if (p == NULL) {
printf("Memory allocation failed, printing only stored values \n");
return q;
}
last += MEM_SIZE;
}
p[current] = c;
temp_counter++;
printf("number of chars: %d\n", temp_counter);
++current;
}
p[current] = '\0';
(*counter) = temp_counter - 1;
return p;
}
void printInput(char *input) {
int i, j = 0;
while (input[j] != '\0') {
for (i = 0; i < LINE; i++) {
if (input[j] == '\0')
break;
putchar(input[j]);
++j;
}
if (input[j] != '\0')
putchar('\n');
}
}

String array prints out trash values

So I have an assignment where I should delete a character if it has duplicates in a string. Right now it does that but also prints out trash values at the end. Im not sure why it does that, so any help would be nice.
Also im not sure how I should print out the length of the new string.
This is my main.c file:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main() {
char string[256];
int length;
printf("Enter char array size of string(counting with backslash 0): \n");
/*
Example: The word aabc will get a size of 5.
a = 0
a = 1
b = 2
c = 3
/0 = 4
Total 5 slots to allocate */
scanf("%d", &length);
printf("Enter string you wish to remove duplicates from: \n");
for (int i = 0; i < length; i++)
{
scanf("%c", &string[i]);
}
deleteDuplicates(string, length);
//String output after removing duplicates. Prints out trash values!
for (int i = 0; i < length; i++) {
printf("%c", string[i]);
}
//Length of new string. The length is also wrong!
printf("\tLength: %d\n", length);
printf("\n\n");
getchar();
return 0;
}
The output from the printf("%c", string[i]); prints out trash values at the end of the string which is not correct.
The deleteDuplicates function looks like this in the functions.c file:
void deleteDuplicates(char string[], int length)
{
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length;)
{
if (string[j] == string[i])
{
for (int k = j; k < length; k++)
{
string[k] = string[k + 1];
}
length--;
}
else
{
j++;
}
}
}
}
There is a more efficent and secure way to do the exercise:
#include <stdio.h>
#include <string.h>
void deleteDuplicates(char string[], int *length)
{
int p = 1; //current
int f = 0; //flag found
for (int i = 1; i < *length; i++)
{
f = 0;
for (int j = 0; j < i; j++)
{
if (string[j] == string[i])
{
f = 1;
break;
}
}
if (!f)
string[p++] = string[i];
}
string[p] = '\0';
*length = p;
}
int main() {
char aux[100] = "asdñkzzcvjhasdkljjh";
int l = strlen(aux);
deleteDuplicates(aux, &l);
printf("result: %s -> %d", aux, l);
}
You can see the results here:
http://codepad.org/wECjIonL
Or even a more refined way can be found here:
http://codepad.org/BXksElIG
Functions in C are pass by value by default, not pass by reference. So your deleteDuplicates function is not modifying the length in your main function. If you modify your function to pass by reference, your length will be modified.
Here's an example using your code.
The function call would be:
deleteDuplicates(string, &length);
The function would be:
void deleteDuplicates(char string[], int *length)
{
for (int i = 0; i < *length; i++)
{
for (int j = i + 1; j < *length;)
{
if (string[j] == string[i])
{
for (int k = j; k < *length; k++)
{
string[k] = string[k + 1];
}
*length--;
}
else
{
j++;
}
}
}
}
You can achieve an O(n) solution by hashing the characters in an array.
However, the other answers posted will help you solve your current problem in your code. I decided to show you a more efficient way to do this.
You can create a hash array like this:
int hashing[256] = {0};
Which sets all the values to be 0 in the array. Then you can check if the slot has a 0, which means that the character has not been visited. Everytime 0 is found, add the character to the string, and mark that slot as 1. This guarantees that no duplicate characters can be added, as they are only added if a 0 is found.
This is a common algorithm that is used everywhere, and it will help make your code more efficient.
Also it is better to use fgets for reading input from user, instead of scanf().
Here is some modified code I wrote a while ago which shows this idea of hashing:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NUMCHAR 256
char *remove_dups(char *string);
int main(void) {
char string[NUMCHAR], temp;
char *result;
size_t len, i;
int ch;
printf("Enter char array size of string(counting with backslash 0): \n");
if (scanf("%zu", &len) != 1) {
printf("invalid length entered\n");
exit(EXIT_FAILURE);
}
ch = getchar();
while (ch != '\n' && ch != EOF);
if (len >= NUMCHAR) {
printf("Length specified is longer than buffer size of %d\n", NUMCHAR);
exit(EXIT_FAILURE);
}
printf("Enter string you wish to remove duplicates from: \n");
for (i = 0; i < len; i++) {
if (scanf("%c", &temp) != 1) {
printf("invalid character entered\n");
exit(EXIT_FAILURE);
}
if (isspace(temp)) {
break;
}
string[i] = temp;
}
string[i] = '\0';
printf("Original string: %s Length: %zu\n", string, strlen(string));
result = remove_dups(string);
printf("Duplicates removed: %s Length: %zu\n", result, strlen(result));
return 0;
}
char *remove_dups(char *str) {
int hash[NUMCHAR] = {0};
size_t count = 0, i;
char temp;
for (i = 0; str[i]; i++) {
temp = str[i];
if (hash[(unsigned char)temp] == 0) {
hash[(unsigned char)temp] = 1;
str[count++] = str[i];
}
}
str[count] = '\0';
return str;
}
Example input:
Enter char array size of string(counting with backslash 0):
20
Enter string you wish to remove duplicates from:
hellotherefriend
Output:
Original string: hellotherefriend Length: 16
Duplicates removed: helotrfind Length: 10

Unexpected output of strlen function

I was trying to implement a function that will modify a string:
The code is as follows:
test.h file :
#ifndef header_file
#define header_file
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char * findWord(char *, char *);
#endif
test.c file:
#include"test.h"
char * findWord(char *array, char *action)
{
char testchar;
int count=0, i=0, j, start = 0, end, wordLength = 0, charCount =0, k=0;
char *temp = malloc(sizeof(char)*400);
char *word = malloc(sizeof(char)*30);
char *replaceString = malloc(sizeof(char)*80);
if(strcmp(action,"replace") == 0)
{
while((testchar = array[i]) != '\0')
{
if(testchar == ',')
{
start = i+1;
i++;
continue;
}
else if(testchar == ':')
{
end = i;
word[charCount] = '\0';
charCount = 0;
printf("Start is: %d \n", start);
for(j=0; j< strlen(array); j++)
{
if(j == start)
{
sprintf(replaceString, "%s%s%s", "replace_",word,"_ii");
printf("Replace String for word %s is %s.\n",word,replaceString);
strcat(temp,replaceString);
j = (j-1)+(strlen(word));
k= strlen(replaceString);
printf("The value of J is %d for word %s.\n",j,word);
}
else
{
temp[k++] = array[j];
}
}
temp[k] = '\0';
k=0;
printf(" Words %s is replaced. The new string is:\n", word);
printf("%s\n",temp);
memset(word,'0',30);
memset(temp,'0',400);
memset(replaceString,'0',80);
i++;
continue;
}
if(testchar != 'Y')
{
word[charCount] = testchar;
charCount++;
}
i++;
}
}
else if(strcmp(action,"MISSING") == 0)
{
}
else if(strcmp(action,"EMPTY") == 0)
{
}
else
printf("Something went wrong.\n");
free(temp);
free(word);
free(replaceString);
}
main.c file:
#include"test.h"
int main()
{
char sc[] = "cn:Y,x509UniqueIdentifier:Y,pseudonym:Y,name:Y,l:Y,street:Y,state:Y,postalAddress:Y,postalCode:Y,telephoneNumber:Y,emailAddress:Y";
findWord(sc, "replace");
return 0;
}
The expected output is:
Replace String for word cn is replace_cn_ii.
replace_cn_ii:Y,x509UniqueIdentifier:Y,pseudonym:Y,name:Y,l:Y,street:Y,state:Y,postalAddress:Y,postalCode:Y,telephoneNumber:Y,emailAddress:Y
.
.
.
10 output.
But It is giving the garbage value due to unexpected behavior of strlen().
The value of word after strcat() function is changed automatically.
Where am I going wrong?
Let me know the issue and how to fix it.
Thanks!
You're calling strcat() on temp, but temp does not contain a valid string. This gives undefined behavior.
You must make sure temp is valid first, i.e. make it an empty string:
*temp = '\0';
Of course you must also make sure the allocation has succeeeded.

Create method to iterate through array and format phone number in C

I am new to programming in C, and I'm working on a simple program to take the user input (a basic phone number, ie: (678)-653.7539), and will output it in standard format).
The approach I took was first taking out all periods, hyphens, and parenthesis.
Currently the program prints out just numbers, however the format I want is:
(xxx) xxx-xxxx
I'm thinking creating a method with an array, and then iterating through (similar to stack?) having it input "(" before i[0] and again after i[2], and so on.
Is this the right approach?
#include <stdio.h>
void removeHyphen( char s[], char x );
void removeLeftParen( char s[], char f );
void removeRightParen( char s[], char g );
void removePeriod( char s[], char h );
int main()
{
char s[50];
printf("Enter your phone number:\n");
scanf("%s", s);
printf( "Your phone number: %.13s\n", s );
removeHyphen( s, '-' );
removeLeftParen(s, '(');
removeRightParen(s, ')');
removePeriod(s, '.');
printf( "Formatted phone number: %.10s\n", s );
getchar();
return 0;
}
void removeHyphen(char s[], char x)
{
int i, j;
for (i = 0 ; s[i] != 0 ; ++i)
{
while(s[i]==x)
{
j=i;
while(s[j]!=0)
{
s[j]=s[j+1];
++j;
}
}
}
}
void removeLeftParen(char s[], char f)
{
int i, j;
for (i = 0 ; s[i] != 0 ; ++i)
{
while(s[i]==f)
{
j=i;
while(s[j]!=0)
{
s[j]=s[j+1];
++j;
}
}
}
}
void removeRightParen(char s[], char g)
{
int i, j;
for (i = 0 ; s[i] != 0 ; ++i)
{
while(s[i]==g)
{
j=i;
while(s[j]!=0)
{
s[j]=s[j+1];
++j;
}
}
}
}
void removePeriod(char s[], char h)
{
int i, j;
for (i = 0 ; s[i] != 0 ; ++i)
{
while(s[i]==h)
{
j=i;
while(s[j]!=0)
{
s[j]=s[j+1];
++j;
}
}
}
}
You know exactly what your end product should look like. It'll be char result[15]. So a simple brute force algorithm would look like:
//set the known characters in the output string
result[ 0 ] = '(';
result[ 4 ] = ')';
result[ 5 ] = ' ';
result[ 9 ] = '-';
result[ 14 ] = '/0'; //null terminator
int index = 0;
//pseudocode
foreach( character in input )
if character is a number
if index == 0, 4, 5, 9
++index;
if index == 14 //we're out of room
print result;
exit;
result[ index++ ] = character;
else
ignore character
Where "character is a number" would probably be the only function you'd need to write.
You may not need all the remove logic. You may just iterate over the input and copy the numeric characters.
Pseudo-code idea:
char output[50]; // better: char output[sizeof input];
// This is essentially processed/normalized input.
// In fact, since we know that it is a 10-digit
// phone number we can just do: char output[10];
// If you ever need to store the phone number for
// long term, the last option may be the best option.
const int n = actual length of input, e.g. strlen()
int j = 0;
for (int i = 0; i < n; ++i) {
if (isdigit((unsigned char) input[i]) {
output[j++] = input[i];
}
}
// Validate 'output', for e.g. check that it has 10 characters
// Print output in desired format
See manual page for isdigit().
A different program structure employing the same idea is the following. While accepting input, scan them as characters and ignore the non-digit characters.
I suggest the use of strtok.
The following is an example
#include <stdio.h>
#include <string.h>
int main(void){
char s[50], f[50];
char *part[3] = { NULL };
char *p;
int i;
printf("Enter your phone number:\n");
scanf("%49s", s);
printf( "Your phone number: %s\n", s );
p = strtok(s, "-().");
for(i=0; p!=NULL && i<3; ++i){
part[i] = p;//Better to add one of the check is made up of numbers.
p = strtok(NULL, "-().");
}
if(i==3){
sprintf(f, "(%s) %s-%s", part[0], part[1], part[2]);
printf( "Formatted phone number: %s\n", f );
} else {
printf("invalid format\n");
}
getchar();
return 0;
}
After you have removed all the unwanted characters you can do this
void printFormatted(char *s)
{
int i;
if (s == NULL)
return;
fputc('(', stdout);
for (i = 0 ; ((i < 3) && (s[i] != '\0')) ; ++i)
fputc(s[i], stdout);
fputc(')', stdout);
fputc(' ', stdout);
if (s[i] == '\0')
return;
for ( ; ((i < 6) && (s[i] != '\0')) ; ++i)
fputc(s[i], stdout);
fputc('-', stdout);
if (s[i] == '\0')
return;
for ( ; s[i] != '\0' ; ++i)
fputc(s[i], stdout);
fputc('\n', stdout);
}
Although you don't really need to remove anything if you are just interested in the output of the program, you could use this
#include <stdio.h>
#include <ctype.h>
void printFormatted(char *phone);
int main()
{
char phone[50];
printf("Enter your phone number: ");
if (scanf("%49s%*c", phone) == 1)
{
printf( "Your input : %s\n", phone);
printf("Formatted phone number : ");
printFormatted(phone);
printf("\n");
}
return 0;
}
int putdigit(char digit)
{
/* Print a charater if it's a digit (0-9) */
if (isdigit((int)digit) == 0)
return 0;
fputc(digit, stdout);
return 1;
}
void printFormatted(char *phone)
{
int i;
int j;
/* Always be safe */
if (phone == NULL)
return;
/* Output the `(' */
fputc('(', stdout);
/* Output 3 digits */
for (i = 0, j = 0 ; ((j < 3) && (phone[i] != '\0')) ; ++i)
j += putdigit(phone[i]);
/* Output the `)' and a space */
fputc(')', stdout);
fputc(' ', stdout);
/* Check if there are more characters */
if (phone[i] == '\0')
return;
/* Output 3 digits */
for (j = 0 ; ((j < 3) && (phone[i] != '\0')) ; ++i)
j += putdigit(phone[i]);
/* Output the hypen */
fputc('-', stdout);
/* Check if there are more characters */
if (phone[i] == '\0')
return;
/* Output the rest of the characters */
for ( ; phone[i] != '\0' ; ++i)
putdigit(phone[i]);
fputc('\n', stdout);
}
Another approach. Build the string per an interpreted format.
#include <ctype.h>
// 0: success, 1 fail
int FormatPhoneNumber(const char *format, char *dest, const char *src) {
int i;
for (i = 0; format[i]; i++) {
if (format[i] == 'x') {
while (!isdigit((unsigned char) *src)) {
if (*src++ == '\0') {
dest[i] = '\0';
return 1; // fail, missing digit
}
}
dest[i] = *src++;
} else {
dest[i] = format[i];
}
}
dest[i] = '\0';
while (*src && !isdigit((unsigned char) *src)) src++;
return *src ? 1 : 0;
}
#include <stdio.h>
int main(void) {
const char format[] = "(xxx) xxx-xxxx";
char buf[sizeof format];
int result = FormatPhoneNumber(format, buf, " (678)-653.7539),");
printf("%d '%s'\n", result, buf);
result = FormatPhoneNumber(format, buf, "Jenny: 111-867-5309");
printf("%d '%s'\n", result, buf);
return 0;
}
0 '(678) 653-7539'
0 '(111) 867-5309'

Resources