Challenge
Conceal a binary code within a word.
Specifications
- The first argument is a path to a file.
- The file contains multiple lines.
- Each line is a test case represented by a space separated word and a binary code.
- For each test case, print the binary masked word.
- The mask alters the word according to the following:
- If the bit is 1, change the letter to upper case.
- If the bit is 0, leave the letter as is.
Constraints
- Words are from 1 to 20 letters long.
- The length of each word is equal to the length of the binary code.
- Words are always in lower case.
- The number of test cases is 40.
Sample Input
hello 11001
world 10000
cba 111
Sample Output
HEllO
World
CBA
My Solution
#include <stdio.h>
#include <ctype.h>
#define LINE_BUFFER 42
int main(int argc, char *args[]) {
if (argc < 2) {
puts("File path not provided.");
return 1;
}
if (argc > 2) {
puts("Excessive arguments, only the first will be considered.");
}
FILE *file = fopen(args[1], "r");
if (file == NULL) {
puts("Could not access file / file not found.");
return 1;
}
char line[LINE_BUFFER];
while (fgets(line, LINE_BUFFER, file)) {
for (int i = 0, word_length = 0; ; i++, word_length++) {
if (line[i] == ' ') {
line[i++] = '0円';
for (int j = 0; j < word_length; j++, i++) {
if (line[i] == '1') {
line[j] = toupper(line[j]);
}
}
printf("%s\n", line);
break;
}
}
}
fclose(file);
}
2 Answers 2
Handling arguments and errors
In C, args
is conventionally called argv
.
Do not contaminate stdout
with error messages, which should go to stderr
instead. One way to write error messages to stderr
is using fprintf(stderr, ...)
. However, a more idiomatic and informative way is using perror()
. For example, perror(args[1])
might print an error message like blah.txt: No such file or directory
.
An even friendlier solution is to interpret the spec in such a way that there aren't so many possible error conditions. For example, if there are no files specified you could just read from stdin
, and if there are multiple files specified you could process them all.
Code structure
I'm not a fan of the while
–for
–if
–for
–if
nesting, especially since the body of if (line[i] == ' ')
only runs once per line. I think that the code would be tidier if you searched for the space delimiter using strchr()
. If you are on a system where strsep()
is available (such as BSD or GNU), use that instead. Otherwise, strtok()
, strtok_r()
, or strtok_s()
could also work.
You don't need printf("%s", ...)
when puts(...)
will do.
Suggested solution
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 42
int toggle_case(FILE *file) {
char line[BUFFER_SIZE], *word, *mask;
while (fgets(line, BUFFER_SIZE, file)) {
if (!(mask = strchr(line, ' '))) {
fprintf(stderr, "Invalid input: %s\n", line);
return -1;
}
for (*mask++ = '0円', word = line; *word && *mask; mask++, word++) {
if (*mask == '1') {
*word = toupper(*word);
}
}
puts(line);
}
return 0;
}
int main(int argc, char *argv[]) {
FILE *file = stdin;
if (argc <= 1) {
toggle_case(stdin);
} else for (int i = 1; i < argc; i++) {
if (NULL == (file = fopen(argv[i], "r"))) {
perror(argv[i]);
return EXIT_FAILURE;
}
int err = toggle_case(file);
fclose(file);
if (err) return EXIT_FAILURE;
}
}
-
1\$\begingroup\$ I agree with everything you said – apart from putting
*mask++ = '0円'
into the for-loop :) \$\endgroup\$Martin R– Martin R2016年09月06日 06:00:17 +00:00Commented Sep 6, 2016 at 6:00
42
#define LINE_BUFFER 42
42
is not a buffer. Besides being a meaning of life, the universe, and everything, it is size. Consider renaming it toLINE_BUFFER_LENGTH
.No naked loops
Every loop represents some algorithm, and therefore deservers a name. Consider
while (fgets(line, LINE_BUFFER, file)) { char * mask = find_separator(line); *mask++ = '0円'; convert_word_according_to_mask(line, mask); printf("%s\n", line); }
Errors (like
fopen
returning NULL) are better handled withperror()
orstrerror(errno)
. Both functions precisely describe what went wrong.
-
-
\$\begingroup\$ @Legato Looks right, but please sep a rator \$\endgroup\$vnp– vnp2016年09月07日 03:50:22 +00:00Commented Sep 7, 2016 at 3:50
Explore related questions
See similar questions with these tags.