Blog
01 – Introducción General
Una introducción rapida a C

1.1 Comencemos
Ejercicio 1-1
Ejecute el programa «hola, mundo» en su sistema. Experimenta con la omisión de partes del programa, para ver qué mensajes de error se obtienen.
#include/* Ejecute el programa "hola, mundo" en su sistema. Experimenta con la omisión de partes del programa, para ver qué mensajes de error se obtienen.*/ int main() { printf("hola, "); printf("mundo"); printf("\n"); }
Ejercicio 1-2
Experimente el descubrir qué pasa cuando la cadena del argumento de printf contiene \c, en donde c es algún carácter no puesto en la lista anterior (\t, \n, \b, \», \\)
#include <stdio.h> /* Experimente el descubrir qué pasa cuando la cadena del argumento de printf contiene \c, en donde c es algún carácter no puesto en la lista anterior (\t, \n, \b, \", \\).*/ int main() { printf("hola, "); printf("mundo \l"); printf("\n"); }
ejer01_02.c: In function 'main': ejer01_02.c:9:10: warning: unknown escape sequence: '\l' printf("mundo \l"); ^~~~~~~~~~
1.2 Variables y expresiones aritméticas
Ejercicio 1-3
Modifique el programa de conversion de temperaturas de modo que escriba un encabezado sobre la tabla.
#include/* Imprime la tabla Fahrenheit-Celsius para fahr = 0, 20, ..., 300 versión de punto flotante*/ main() { float fahr, celsius; float lower, upper, step; printf("Fahrenheit\tCelsius\n"); printf("=======================\n"); lower = 0; /* límite inferior de la tabla de temperatura */ upper = 300; /* límite superior de la tabla de temperatura */ step = 20; /* tamaño del incremento */ fahr = lower; while (fahr <= upper) { celsius = (5.0/9.0) * (fahr - 32); printf("%3.0f\t\t %6.1f\n", fahr, celsius); fahr = fahr + step; } }
Fahrenheit Celsius ======================= 0 -17.8 20 -6.7 40 4.4 60 15.6 80 26.7 100 37.8 120 48.9 140 60.0 160 71.1 180 82.2 200 93.3 220 104.4 240 115.6 260 126.7 280 137.8 300 148.9
Ejercicio 1-4
Escriba un programa que imprima la tabla correspondiente Celsius a Fahrenheit.
#include/* Imprime la tabla Celsius_Fahrenheit para celsius = 0, 20, ..., 300 versión de punto flotante*/ main() { float fahr, celsius; float lower, upper, step; printf("Celsius\tFahrenheit\n"); printf("==================\n"); lower = 0; /* límite inferior de la tabla de temperatura */ upper = 300; /* límite superior de la tabla de temperatura */ step = 20; /* tamaño del incremento */ celsius = lower; while (celsius <= upper) { fahr = (9.0/5.0) * celsius - 32; printf(" %3.0f\t %6.1f\n", celsius, fahr); celsius = celsius + step; } }
Celsius Fahrenheit ================== 0 -32.0 20 4.0 40 40.0 60 76.0 80 112.0 100 148.0 120 184.0 140 220.0 160 256.0 180 292.0 200 328.0 220 364.0 240 400.0 260 436.0 280 472.0 300 508.0
1.3 La proposición for
Ejercicio 1-5
Modifique el programa de conversión de temperaturas de manera que escriba la tabla en orden inverso, esto es, desde 300 grados hasta 0.
#includeint main() { float fahr; printf(" Fahrenheit\tCelsius\n"); printf("=======================\n"); for(fahr = 300; fahr > 0; fahr = fahr - 20) printf("\t%3.0f\t %6.1f\n", fahr, (5.0/9.0)*(fahr-32)); }
Fahrenheit Celsius ======================= 300 148.9 280 137.8 260 126.7 240 115.6 220 104.4 200 93.3 180 82.2 160 71.1 140 60.0 120 48.9 100 37.8 80 26.7 60 15.6 40 4.4 20 -6.7
1.4 Constantes simbólicas
1.5 Entrada y salida de caracteres
Ejercicio 1-6
Verifique que la expresión getchar() != EOF
es 0 o 1
#include/* copia la entrada a la salida*/ int main(void) { int c; int valor; printf("Comienzo programa\n"); valor = (c=getchar())!=EOF; printf("El valor es %d\n", valor); /*while((c = getchar()) != EOF){ putchar(c); }*/ return 0; }
Comienzo programa ^D El valor es 1
Ejercicio 1-7
Escriba un programa que imprima el valor de EOF.
#include/* copia la entrada a la salida */ int main(void) { printf("El valor de fin de fichero es %d",EOF); return 0; }
El valor de fin de fichero es -1
Ejercicio 1-8
Escriba un programa que cuente espacios en blanco, tabuladores y nuevas líneas.
#include/* cuenta las líneas de la entrada, los espacios en blanco y los tabuladores */ int main(void) { int c, nl, eb, nt; nl = 0; # nuevas líneas eb = 0; # espacios en blanco nt = 0; # tabuladores while((c = getchar()) != EOF){ if(c == '\n') ++nl; if(c == ' ') ++eb; if(c == '\t') ++nt; } printf("Líneas: %d\nEspacios: %d\nTabuladores: %d\n", nl, eb, nt); return 0; }
Ejercicio 1-9
Escriba un programa que copie su entrada a la salida, reemplazando cada cadena de uno o más blancos por un solo blanco.
#include/* Escriba un programa que copie su entrada a la salida, reemplazando cada cadena de uno o más blancos por un solo blanco. */ int main(void) { int c, eb; eb = 0; while((c = getchar()) != EOF){ if(c==' '){ ++eb; } else { if(eb>0){ eb=0; putchar(' '); } putchar(c); } } return 0; }
Ejercicio 1-10
Escriba un programa que copie su entrada a la salida, reemplazando cada tabulación por \t, cada retroceso por \b y cada diagonal invertida por \\. Esto hace que las tabulaciones y los espacios sean visibles sin confusiones
#include/* Escriba un programa que copie su entrada a la salida, reemplazando cada tabulación por \t, cada retroceso por \b y cada diagonal invertida por \\. Esto hace que las tabulaciones y los espacios sean visibles sin confusiones */ int main(void) { int c; while((c = getchar()) != EOF){ if(c=='\t'){ putchar('\\'); putchar('t'); } else if(c=='\b'){ putchar('\\'); putchar('b'); } else if(c=='\\'){ putchar('\\'); putchar('\\'); } else putchar(c); } return 0; }
Ejercicio 1-11
¿Cómo probaría el programa para contar palabras? ¿Qué clase de entrada es la más conveniente para descubrir errores si éstos existen?
#include#define IN 1 /* en una palabra */ #define OUT 0 /* fuera de una palabra */ /* cuenta líneas, palabras y caracteres de la entrada */ int main() { int c, nl, nw, nc, state; state = OUT; nl = nw = nc = 0; while((c = getchar()) != EOF) { ++nc; if(c == '\n') ++nl; if(c == ' ' || c == '\n' || c == '\t') state = OUT; else if(state == OUT) { state = IN; ++nw; } } printf("Lineas %d, palabras %d, caracteres %d", nl, nw, nc); return 0; }
>type lineas.c | ejer01_11 El sistema no puede encontrar el archivo especificado. Lineas 0, palabras 0, caracteres 0 >type lineas01.c | ejer01_11 Lineas 13, palabras 33, caracteres 189
Ejercicio 1-12
Escriba un programa que imprima su entrada una palabra por linea.
#include#define IN 1 #define OUT 0 int main() { int c, estado; estado = OUT; while ((c = getchar()) != EOF) { if (c == ' ' || c == '\n' || c == '\t') { if (estado == IN) { putchar('\n'); estado = OUT; } } else { putchar(c); estado = IN; } } return 0; }
1.6 Arreglos
Ejercicio 1-13
Escriba un programa que imprima el histograma de las longitudes de las palabras de su entrada de forma horizontal.
#include#define IN 1 #define OUT 0 #define LARGO_MAXIMO 10 /* máximo tamaño de una palabra */ int main() { int c, i, j, estado, largo; int longitudPalabras[LARGO_MAXIMO + 1]; /* array que guarda la frecuencia de cada longitud de palabra */ for (i = 0; i <= LARGO_MAXIMO; ++i) longitudPalabras[i] = 0; estado = OUT; largo = 0; /* contar la frecuencia de cada longitud de palabra */ while ((c = getchar()) != EOF) { if (c == ' ' || c == '\n' || c == '\t') { if (estado == IN) { if (largo <= LARGO_MAXIMO) ++longitudPalabras[largo]; else ++longitudPalabras[LARGO_MAXIMO]; largo = 0; } estado = OUT; } else { estado = IN; ++largo; } } /* imprimir el histograma */ for (i = 1; i <= LARGO_MAXIMO; ++i) { printf("%2d: ", i); for (j = 0; j < longitudPalabras[i]; ++j) putchar('*'); putchar('\n'); } /* imprimir la frecuencia de palabras con longitud mayor que LARGO_MAXIMO */ if (longitudPalabras[LARGO_MAXIMO] > 0) printf("%2d+: %d\n", LARGO_MAXIMO, longitudPalabras[LARGO_MAXIMO]); return 0; }
Ejercicio 1-13b
Escriba un programa que imprima el histograma de las longitudes de las palabras de su entrada. Hacerlo con orientación vertical es un reto más interesante
#include#define IN 1 #define OUT 0 #define LARGO_MAXIMO 10 /* máximo tamaño de una palabra */ int main() { int c, i, j, estado, largo; int longitudPalabras[LARGO_MAXIMO + 1]; /* array que guarda la frecuencia de cada longitud de palabra */ for (i = 0; i <= LARGO_MAXIMO; ++i) longitudPalabras[i] = 0; estado = OUT; largo = 0; /* contar la frecuencia de cada longitud de palabra */ while ((c = getchar()) != EOF) { if (c == ' ' || c == '\n' || c == '\t') { if (estado == IN) { if (largo <= LARGO_MAXIMO) ++longitudPalabras[largo]; else ++longitudPalabras[LARGO_MAXIMO]; largo = 0; } estado = OUT; } else { estado = IN; ++largo; } } /* encontrar el máximo número de asteriscos en una barra */ int maxCount = 0; for (i = 1; i <= LARGO_MAXIMO; ++i) { if (longitudPalabras[i] > maxCount) maxCount = longitudPalabras[i]; } if (longitudPalabras[LARGO_MAXIMO] > maxCount) maxCount = longitudPalabras[LARGO_MAXIMO]; /* imprimir el histograma en vertical */ for (i = maxCount; i > 0; --i) { printf("%2d |", i); for (j = 1; j <= LARGO_MAXIMO; ++j) { if (longitudPalabras[j] >= i) printf(" * "); else printf(" "); } if (longitudPalabras[LARGO_MAXIMO] >= i) printf(" *"); putchar('\n'); } /* imprimir la línea de separación */ printf(" +"); for (i = 1; i <= LARGO_MAXIMO; ++i) printf("---"); printf("---"); putchar('\n'); /* imprimir la etiqueta de cada barra */ printf(" "); for (i = 1; i <= LARGO_MAXIMO; ++i) printf("%2d ", i); printf("%2d+", LARGO_MAXIMO); putchar('\n'); return 0; }
1.7 Funciones
Ejercicio 1-15
Escriba de nuevo el programa de conversión de temperatura de la sección 1.2, de modo que utilice una función para la conversión.
#include/* Imprime la tabla Fahrenheit-Celsius para fahr = 0, 20, ..., 300 versión de punto flotante*/ int fahrToCel(int f); int main() { float fahr, celsius; float lower, upper, step; printf("Fahrenheit\tCelsius\n"); printf("=======================\n"); lower = 0; /* límite inferior de la tabla de temperatura */ upper = 300; /* límite superior de la tabla de temperatura */ step = 20; /* tamaño del incremento */ fahr = lower; while (fahr <= upper) { //celsius = (5.0/9.0) * (fahr - 32); celsius = fahrToCel(fahr); printf("%3.0f\t\t %6.1f\n", fahr, celsius); fahr = fahr + step; } return 0; } int fahrToCel(int f) { int c; c = (5.0/9.0) * (f - 32); return c; }
1.8 Argumentos - llamadas por valor
1.9 Arreglos de caracteres
Ejercicio 1-16
Corrija la rutina principal del programa de la línea más larga de modo que imprima correctamente la longitud de líneas de entrada arbitrariamente largas, y tanto texto como sea posible.
#include#define MAXLINE 1000 /* tamaño máximo de la línea de entrada*/ /* Escribir un programa que lea un conjunto de líneas de texto e imprima la de mayor longitud Arreglar el programa para que imprima correctamente la longitud de líneas de entrada arbitrariamente largas, y tanto texto como sea posible. */ int getlinea(char line[], int maxline); void copy(char to[], char from[]); int main() { int len; /* longitud actual de la línea */ int max; /* máxima longitud vista hasta el momento */ char line[MAXLINE]; /* línea de entrada actual */ char longest[MAXLINE]; /* la linea más larga se guarda aquí*/ max = 0; while((len = getlinea(line, MAXLINE)) > 0) if(len > max) { max = len; copy(longest, line); } if(max > 0){ /* hubo una línea */ printf("La longitud de la linea es %d\n", max); printf("%s\n", longest); } return 0; } /* getlinea: lee una línea en s, regresa su longitud */ int getlinea(char s[], int lim) { int c, i; for(i=0; i < lim-1 && (c = getchar()) != EOF && c != '\n'; ++i) s[i] = c; if(c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return i; } /* copy: copia 'from' en 'to'; supone que to es suficientemente grande */ void copy(char to[], char from[]) { int i; i = 0; while((to[i] = from[i]) != '\0') ++i; }
Ejercicio 1-17
Escriba un programa que imprima todas las líneas de entrada que sean mayores de 80 caracteres
#include#define MAXLINE 1000 /* tamaño máximo de la línea de entrada*/ /* Escriba un programa que imprima todas las líneas de entrada que sean mayores de 80 caracteres. */ int getlinea(char line[], int maxline); int main() { int len; /* longitud actual de la línea */ char line[MAXLINE]; /* línea actual */ while ((len = getlinea(line, MAXLINE)) > 0) { if (len > 80) { /* si la longitud > 80, imprime */ printf("%s", line); } } return 0; } /* getline: lee una línea en s, regresa su longitud */ int getlinea(char s[], int lim) { int c, i; for (i = 0; i < lim-1 && (c = getchar()) != EOF && c != '\n'; ++i) { s[i] = c; } if (c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return i; }
Ejercicio 1-18
Escriba una función reverse(s) que invierta la cadena de caracteres s. Úsela para escribir un programa que invierta su entrada, línea a línea.
#include#include /* Escribir una funcion reverse(s) ue invierta la cadena de caracteres s. Usarla para escribir un programa que invierta su entrada, línea a línea */ void reverse(char s[]) { int i, j; char c; for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } int main() { char line[1000]; while (fgets(line, sizeof(line), stdin)) { reverse(line); printf("%s\n", line); } return 0; }
1.10 Variables externas y alcance
Ejercicio 1-20
Escribir un programa detab en C que reemplace tabuladores de la entrada con el número apropiado de blancos para espaciar hasta el siguiente paro de tabulación. Considerar un conjunto fijo de paros de tabulación, digamos cada n columnas. ¿debería ser n una variable o un parámetro simbólico?
/* Escribir un programa detab en C que reemplace tabuladores de la entrada con el número apropiado de blancos para espaciar hasta el siguiente paro de tabulación. Considerar un conjunto fijo de paros de tabulación, digamos cada n columnas. ¿debería ser n una variable o un parámetro simbólico? */ #include#define TAB_WIDTH 4 int main() { int c; int pos = 0; while ((c = getchar()) != EOF) { if (c == '\t') { int spaces = TAB_WIDTH - (pos % TAB_WIDTH); for (int i = 0; i < spaces; i++) { putchar(' '); pos++; } } else if (c == '\n') { putchar(c); pos = 0; } else { putchar(c); pos++; } } return 0; }
En respuesta a la pregunta, si el ancho de tabulador debe ser una variable o un parámetro simbólico, la respuesta depende de si se espera que el ancho de tabulador cambie en tiempo de ejecución o si es una constante en el programa. Si el ancho de tabulador es constante, como en este ejemplo, entonces se puede definir como una constante o un macro, como se ha hecho aquí. Si se espera que el ancho de tabulador cambie en tiempo de ejecución, entonces debería ser una variable que se pueda cambiar en algún momento antes de su uso.
Ejercicio 1-21
Escribir un programa en C que reemplace cadenas de blancos por el mínimo número de tabuladores y blancos para obtener el mismo espaciado. Considerar los paros de tabulación de igual manera que en programa anterior. Cuando un tabulador o un simple espacio en blanco fuese suficiente para alcanzar un paro de tabulación, ¿a cuál se le debe dar preferencia?
/* Escribir un programa en C que reemplace cadenas de blancos por el mínimo número de tabuladores y blancos para obtener el mismo espaciado. Considerar los paros de tabulación de igual manera que en programa anterior. Cuando un tabulador o un simple espacio en blanco fuese suficiente para alcanzar un paro de tabulación, ¿a cuál se le debe dar preferencia? */ #include#define TAB_WIDTH 4 int main() { int c; int pos = 0; int space_count = 0; int tab_count = 0; while ((c = getchar()) != EOF) { if (c == ' ') { space_count++; pos++; } else { if (space_count > 0) { int spaces_needed = TAB_WIDTH - (pos % TAB_WIDTH); int tabs_needed = spaces_needed / TAB_WIDTH; spaces_needed = spaces_needed % TAB_WIDTH; if (space_count >= spaces_needed) { tab_count += tabs_needed; space_count -= spaces_needed; putchar('\t'); } while (tab_count > 0) { putchar('\t'); tab_count--; } while (space_count > 0) { putchar(' '); space_count--; } } putchar(c); if (c == '\t') { pos += TAB_WIDTH - (pos % TAB_WIDTH); } else if (c == '\n') { pos = 0; } else { pos++; } } } return 0; }
En este ejemplo, el programa mantiene dos contadores para realizar un seguimiento del número de espacios y pestañas en una cadena de espacios. Cuando se encuentra un carácter que no sea un espacio, el programa verifica si hay una cadena de espacios previa y calcula el número mínimo de pestañas y espacios necesarios para producir el mismo espaciado. Si un solo espacio es suficiente para alcanzar un paro de tabulación, el programa dará preferencia a un espacio en blanco.
En respuesta a la pregunta, si un tabulador o un espacio en blanco es preferible cuando un solo espacio en blanco es suficiente para alcanzar un paro de tabulación, la respuesta depende de la preferencia del usuario o del estándar utilizado. Por ejemplo, en el estándar POSIX, se indica que se debe dar preferencia a los espacios en blanco. Por lo tanto, en este ejemplo, el programa da preferencia a los espacios en blanco en caso de que un solo espacio sea suficiente para alcanzar un paro de tabulación.
Ejercicio 1-22
Escribir un programa en C para "doblar" líneas grandes de entrada en dos o más líneas más cortas después del último carácter no blanco que ocurra antes de la n-ésima columna de entrada. Asegurarse de que el programa se comporte apropiadamente con líneas muy largas y de que no haya blancos o tabuladores antes de la columna especificada.
/* Escribir un programa en C para "doblar" líneas grandes de entrada en dos o más líneas más cortas después del último carácter no blanco que ocurra antes de la n-ésima columna de entrada. Asegurarse de que el programa se comporte apropiadamente con líneas muy largas y de que no haya blancos o tabuladores antes de la columna especificada. */ #include#define MAX_LINE_LENGTH 1000 #define MAX_LINE_WIDTH 80 int main() { int c; int line_length = 0; char line[MAX_LINE_LENGTH]; int i = 0; while ((c = getchar()) != EOF) { if (line_length == MAX_LINE_WIDTH) { // La línea ha alcanzado la longitud máxima permitida. // Buscamos el último carácter no blanco. int last_non_blank = -1; for (int j = MAX_LINE_WIDTH - 1; j >= 0; j--) { if (line[j] != ' ' && line[j] != '\t') { last_non_blank = j; break; } } if (last_non_blank == -1) { // No hay caracteres no blancos en la línea. // Simplemente dividimos la línea en dos en la columna especificada. for (int j = 0; j < MAX_LINE_WIDTH; j++) { putchar(line[j]); } putchar('\n'); for (int j = MAX_LINE_WIDTH; j < line_length; j++) { putchar(line[j]); } line_length -= MAX_LINE_WIDTH; } else if (last_non_blank == MAX_LINE_WIDTH - 1) { // El último carácter no blanco está en la última columna. // Simplemente dividimos la línea en dos en la columna especificada. for (int j = 0; j < MAX_LINE_WIDTH; j++) { putchar(line[j]); } putchar('\n'); for (int j = MAX_LINE_WIDTH; j < line_length; j++) { putchar(line[j]); } line_length -= MAX_LINE_WIDTH; } else { // Dividimos la línea en dos en el último carácter no blanco. for (int j = 0; j <= last_non_blank; j++) { putchar(line[j]); } putchar('\n'); for (int j = last_non_blank + 1; j < line_length; j++) { putchar(line[j]); } line_length -= last_non_blank + 1; } } if (c == '\n') { // Nueva línea line_length = 0; i = 0; } else { // Agregamos el carácter a la línea actual if (line_length < MAX_LINE_LENGTH - 1) { line[i++] = c; line_length++; } } } return 0; }
Ejercicio 1-23
Escribir un programa en C para eliminar todos los comentarios de un programa en C. No te olvides de manejar apropiadamente las cadenas entre comillas y las constantes de carácter. Los comentarios de C no se anidan.
/* Escribir un programa en C para eliminar todos los comentarios de un programa en C. No te olvides de manejar apropiadamente las cadenas entre comillas y las constantes de carácter. Los comentarios de C no se anidan. */ #include#include int main(void) { int c; bool inside_string = false; // Indica si estamos dentro de una cadena entre comillas bool inside_char = false; // Indica si estamos dentro de una constante de carácter while ((c = getchar()) != EOF) { if (c == '\"' && !inside_char) { inside_string = !inside_string; putchar(c); } else if (c == '\'' && !inside_string) { inside_char = !inside_char; putchar(c); } else if (!inside_string && !inside_char) { if (c == '/') { c = getchar(); if (c == '*') { // Comentario de varias líneas while ((c = getchar()) != EOF) { if (c == '*') { c = getchar(); if (c == '/') { break; } else { ungetc(c, stdin); } } } } else if (c == '/') { // Comentario de una sola línea while ((c = getchar()) != EOF && c != '\n') { // Descartamos el comentario } if (c != EOF) { putchar('\n'); } } else { putchar('/'); if (c != EOF) { putchar(c); } } } else { putchar(c); } } else { putchar(c); } } return 0; }
El programa utiliza dos variables booleanas inside_string e inside_char para indicar si se está dentro de una cadena entre comillas o una constante de carácter, respectivamente. Si estamos dentro de una de estas estructuras, el programa simplemente imprime el carácter sin hacer ningún tipo de análisis. Si no estamos dentro de ninguna de estas estructuras, el programa examina el carácter para determinar si es el comienzo de un comentario. Si es así, el programa procesa el comentario de forma apropiada. Si no, el programa simplemente imprime el carácter.
El programa distingue entre comentarios de una sola línea (comenzando con //) y comentarios de varias líneas (comenzando con /* y terminando con */). En ambos casos, el programa descarta todos los caracteres correspondientes al comentario antes de continuar con la entrada.
Es importante notar que este programa no es capaz de manejar comentarios anidados, ya que los comentarios de C no se anidan. Sin embargo, el programa debería ser capaz de manejar apropiadamente todas las situaciones en las que se utilizan comentarios en un programa típico en C.
Ejercicio 1-24
Escribir un programa para revisar los errores de sintaxis rudimentarios de un programa en C, como paréntesis, llaves y corchetes no alineados. No olvidar las comillas ni los apóstrofos, las secuencias de escape y los comentarios.
/* Escribir un programa para revisar los errores de sintaxis rudimentarios de un programa en C, como paréntesis, llaves y corchetes no alineados. No olvidar las comillas ni los apóstrofos, las secuencias de escape y los comentarios. */ #includeint main() { int c, i, line_num; int parens, braces, brackets, quotes; parens = braces = brackets = quotes = 0; line_num = 1; while ((c = getchar()) != EOF) { if (c == '\n') { line_num++; } else if (c == '(') { parens++; } else if (c == ')') { parens--; if (parens < 0) { printf("Error: paréntesis desalineados en línea %d\n", line_num); return 1; } } else if (c == '{') { braces++; } else if (c == '}') { braces--; if (braces < 0) { printf("Error: llaves desalineadas en línea %d\n", line_num); return 1; } } else if (c == '[') { brackets++; } else if (c == ']') { brackets--; if (brackets < 0) { printf("Error: corchetes desalineados en línea %d\n", line_num); return 1; } } else if (c == '"' || c == '\'') { quotes++; i = 1; while ((c = getchar()) != EOF) { if (c == '\\') { i++; c = getchar(); } else if (c == '"' || c == '\'') { quotes--; break; } i++; } if (quotes < 0) { printf("Error: comillas o apóstrofos desalineados en línea %d\n", line_num); return 1; } } } if (parens > 0) { printf("Error: paréntesis desalineados en línea %d\n", line_num); return 1; } else if (braces > 0) { printf("Error: llaves desalineadas en línea %d\n", line_num); return 1; } else if (brackets > 0) { printf("Error: corchetes desalineados en línea %d\n", line_num); return 1; } else if (quotes > 0) { printf("Error: comillas o apóstrofos desalineados en línea %d\n", line_num); return 1; } else { printf("Sintaxis correcta\n"); return 0; } }
Este programa examina cada carácter de la entrada y mantiene un registro de los paréntesis, llaves, corchetes y comillas. Si se encuentra un paréntesis, llave o corchete izquierdo, el contador correspondiente se incrementa, y si se encuentra uno derecho, se decrementa. Si en algún momento el contador es menor que cero, se produce un error de sintaxis y se imprime un mensaje de error.
Por último, se verifica si hay algún carácter no válido fuera de una cadena o comentario, y se imprime un mensaje de error si se encuentra alguno.
Este programa solo cubre errores de sintaxis rudimentarios, por lo que todavía es posible que un programa tenga errores lógicos o de otro tipo incluso si pasa la verificación de sintaxis.