- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
对于 C 编程作业,我正在尝试编写几个头文件来检查所谓的“X 编程语言”的语法。我最近才开始,正在编写第一个头文件。这是我编写的代码:
#ifndef _DeclarationsChecker_h_
#define _DeclarationsChecker_h_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define LINE_LENGTH_LIMIT 200
#define CODE_LINE_LIMIT 1000
void checkDeclarations(char **code, int num_lines) {
char *currentLine;
for (int currentLineNum = 0; currentLineNum < num_lines; currentLineNum++) {
if (code[currentLineNum] != NULL) {
currentLine = code[currentLineNum];
char (**tokenized)[LINE_LENGTH_LIMIT];
for (int i = 0; i < strlen(currentLine); i++) {
tokenized[i] = strtok(currentLine, " ");
if (tokenized[i] == NULL)
break;
}
char *currentToken;
for (int i = 0; i < LINE_LENGTH_LIMIT; i++) {
currentToken = tokenized[i];
if (strcmp("***", currentToken))
break;
char (*nextToken) = tokenized[i + 1];
if (strcmp("global", currentToken)) {
if (!strcmp("character", nextToken) && !strcmp("integer", nextToken) && !strcmp("double", nextToken) && !strcmp("string", nextToken)) {
printf("Declarations: unknown data type %s at line %d", nextToken, currentLineNum);
}
}
if (strcmp("character", currentToken) || strcmp("integer", currentToken) || strcmp("double", currentToken) || strcmp("string", currentToken)) {
char *functionName = strtok(nextToken, '(');
if (strcmp("character", functionName) || strcmp("integer", functionName) || strcmp("double", functionName) || strcmp("string", functionName) || strcmp("while", functionName) || strcmp("if", functionName) || strcmp("else", functionName) || strcmp("global", functionName) || strcmp("equal", functionName) || strcmp("nequal", functionName) || strcmp("return", functionName)) {
printf("Declarations: naming violation of %s at line %d", functionName, currentLineNum);
}
for (int i = 0; i < strlen(functionName); i++) {
if (!isalnum(functionName[i]) && (functionName[i] != '_') && (functionName[i] != '?')) {
printf("Declarations: naming violation of %s at line %d", functionName, currentLineNum);
}
}
}
}
}
}
}
#endif
我得到了几个编译警告,我将警告添加到最后,当我尝试启动程序时,它立即给出了“程序崩溃”的错误,但我认为可能是因为尚未编写头文件。我该怎么做才能摆脱我遇到的错误?感谢您的回答,我们将不胜感激任何帮助。 (请注意,我是 C 的新手,我不太了解数组和指针以及双指针之间的互换性概念(例如:**ptr))
...\declarationschecker.h(30): warning C4018: '<': signed/unsigned mismatch
...\declarationschecker.h(32): warning C4047: '=': 'char (*)[200]' differs in levels of indirection from 'char *'
...\declarationschecker.h(42): warning C4047: '=': 'char *' differs in levels of indirection from 'char (*)[200]'
...\declarationschecker.h(59): warning C4047: 'function': 'const char *' differs in levels of indirection from 'int'
...\declarationschecker.h(59): warning C4024: 'strtok': different types for formal and actual parameter 2
...\declarationschecker.h(66): warning C4018: '<': signed/unsigned mismatch
...\declarationschecker.h(47): warning C4047: 'initializing': 'char *' differs in levels of indirection from 'char (*)[200]'
需要头文件的主要c文件贴在下面:
#include "CodeReader.h"
#include "BracketsChecker.h"
#include "DeclarationsChecker.h"
#include "StatementsChecker.h"
#include "SSAChecker.h"
int main(int argc, char * argv[]) {
if (argc < 2) {
printf("Please provide X code file name\n");
exit(1);
}
char **code = readCode(argv[1]);
int num_lines = getCodeNumLines();
checkBrackets(code, num_lines);
checkDeclarations(code, num_lines);
checkProgramStatements(code, num_lines);
checkSSA(code, num_lines);
cleanMemory(code);
int terminalHung; scanf("%d", &terminalHung);
return 0;
}
最佳答案
首先,如果无法访问项目的其余部分(我假设还有其他几个文件包含您在帖子中引用的一些函数),则无法知道您是如何创建代码的生成器,将建议限制在句法问题上。
您帖子中的以下错误的解释在下面的评论和底部代码中的内联评论中:
首先,在您编辑的部分中,我看不到函数 readCode()
是什么,因为您没有包含它,但如果它不创建内存,那么变量 code
不能使用。
在声明 char (**tokenized)[LINE_LENGTH_LIMIT];
之后,您尝试使用 char **
的第零个数组元素而不先创建内存。充其量,您的程序会在运行时崩溃,更糟糕的是,它似乎可以正常工作。这称为 Undefined 或 Unspecified behavior 。 (阅读如何使用 malloc )。因为您正在为字符串集合准备存储,所以您只需要两个维度,而不是三个。 char *[]
或 char **
都可以。在任何一种情况下,这些都必须在使用前初始化并创建内存。但是,由于您已经知道最大行数和最大行长度,只需声明并使用:char tokenized[CODE_LINE_LIMIT][LINE_LENGTH_LIMIT];
。
此外,声明 char *token = 0;
以与 strtok 一起使用。 (原因见评论)
此外,声明一次多次使用的变量(例如i
。请参阅注释了解原因)
对于其余部分,再次查看行内注释以查看您的代码中先前的错误/警告是如何解决的:
static void checkDeclarations(char **code, int num_lines)
{
char *token = 0;//use with strtok
char *currentLine;
char tokenized[CODE_LINE_LIMIT][LINE_LENGTH_LIMIT] = {{0}};
int i, len; // declare multiply used variables once
for (int currentLineNum = 0; currentLineNum < num_lines; currentLineNum++) {
if (code[currentLineNum] != NULL) {
currentLine = code[currentLineNum];
//char (*tokenized)[LINE_LENGTH_LIMIT] = {0};
len = strlen(currentLine);
for( i = 0; i< len; i++ ) // corrected
//for (int i = 0; i < strlen(currentLine); i++) // don't do string comparison's in a loop
{ // and avoid comparisons of different types
// return of strlen() is an unsigned int
token = strtok(currentLine, " ");
if (token == NULL) break;
else strcpy(tokenized[i], token);
}
char *currentToken;
//for (int i = 0; i < LINE_LENGTH_LIMIT; i++) { // shadow declaration of previously declared variable
for ( i = 0; i < LINE_LENGTH_LIMIT; i++) { // corrected
currentToken = tokenized[i];
if (strcmp("***", currentToken))
break;
char (*nextToken) = tokenized[i + 1];
if (strcmp("global", currentToken)) {
if (!strcmp("character", nextToken) && !strcmp("integer", nextToken) && !strcmp("double", nextToken) && !strcmp("string", nextToken)) {
printf("Declarations: unknown data type %s at line %d", nextToken, currentLineNum);
}
}
if (strcmp("character", currentToken) || strcmp("integer", currentToken) || strcmp("double", currentToken) || strcmp("string", currentToken)) {
//char *functionName = strtok(nextToken, '('); // strtok 2nd argument requires a string, not an integer
char *functionName = strtok(nextToken, "("); // corrected
// note: calling this in a loop will be a problem. either Declare 'functionName' at top of function
// or use 'token', already declared
if (strcmp("character", functionName) || strcmp("integer", functionName) || strcmp("double", functionName) || strcmp("string", functionName) || strcmp("while", functionName) || strcmp("if", functionName) || strcmp("else", functionName) || strcmp("global", functionName) || strcmp("equal", functionName) || strcmp("nequal", functionName) || strcmp("return", functionName)) {
printf("Declarations: naming violation of %s at line %d", functionName, currentLineNum);
}
//for (int i = 0; i < strlen(functionName); i++) { // "i" has already been declared above
for ( i = 0; i < len; i++) { // corrected
if (!isalnum(functionName[i]) && (functionName[i] != '_') && (functionName[i] != '?')) {
printf("Declarations: naming violation of %s at line %d", functionName, currentLineNum);
}
}
}
}
}
}
}
编辑以解决评论中的问题...
您可能已经知道以下内容,但您的帖子没有给出任何指示,因此我提供以下内容以防万一:
在将字符串分配给 char *str
之前(例如,通过使用 strcpy
或 strcat
等),您必须创建内存:
int desiredStrLen = 80;
char *str = calloc(desiredStrLen + 1, 1);
if(str)// test return of calloc before trusting it worked
{
//use str
...
free(str); // always, when finished with any dynamically allocated memory, free it.
对于字符串集合(例如,读取文件行时需要),您可以为一组字符串创建内存。一旦确定了行数以及文件中的最长行,您就可以创建足够的内存来将从文件中读取的每一行复制到一个字符串中:
char **currentLine = Create2DStr(numLines, longestLine);
if(strings)
{
/// use currentLine (in your loop)
...
strcpy(currentLine[i], code[currentLineNum]);
...
// when finished with string collection, free it.
free2DStr(&strings, numLines);
我在上面使用的功能可以通过多种方式实现。我使用以下内容:
char ** Create2DStr(ssize_t numStrings, ssize_t maxStrLen)
{
int i;
char **str = {0};
str = calloc(numStrings, sizeof(char *));
for(i=0;i<numStrings; i++)
{
str[i] = calloc(maxStrLen + 1, 1);
}
return str;
}
void free2DStr(char *** str, ssize_t numStrings)
{
int i;
if(!(*str)) return;
for(i=0;i<numStrings; i++)
{
free((*str)[i]);
(*str)[i] = NULL;
}
free((*str));
(*str) = NULL;
}
关于C - 字符 *' differs in levels of indirection from ' 字符 (*)[200],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50077501/
我知道这类问题已经得到解答,但就我而言,我已经尝试了所有配置,但仍然不起作用。我需要对我的配置有一个新的看法(我确信我错过了一些东西)。两个附加程序都会记录所有级别 我想将所有包的信息 >= 记录到控
我正在对 Windows 移动设备上的代码性能进行一些基准测试,并注意到某些算法在某些主机上的表现明显更好,而在其他主机上则明显更差。当然,考虑到时钟速度的差异。 供引用的统计数据(所有结果均由同一个
我有一个程序可以计算多边形的面积和周长。程序还会确认面积和周长的计算结果是否与预期结果相同。 我不明白发生了什么,但确认面积和周长是否与预期相同的验证部分无法正常工作。 例如,我现在测试并在所有情况下
Codepen :(对于那些想直接进入的人来说,这是一个代码笔。在 Chrome 和 IE 中尝试一下,看看结果的不同) 我正在尝试使用 css3 转换/过渡,因为它们比 jquery 效果更流畅。
我有几个不同的正则表达式要在给定文本中匹配和替换。 regex1 :如果文本包含单词“Founder”,则将所有文本替换为首席执行官 正则表达式2:如果文本包含9位数字,则将其替换为NUM 我尝试使用
我编写了多线程应用程序,它从每个线程的数据库连接到一些电子邮件帐户。我知道 JavaMail 没有任何选项可以使用 SOCKS5 进行连接,因此我决定通过 System.setProperty 方法使
如您所见,这是我当前 Storyboard的不同设备预览。底部的透明绿色被另一个 View Controller 占用,但需要为每个不同的尺寸类固定间距。我尝试将 Storyboard 中的宽度和高度
我正在创建一个游戏,我需要能够改变玩家 Sprite 的速度。我认为最好的选择是通过重力影响 Sprite 。为了给用户运动的感觉,我希望背景以完全相同的速度向相反的方向移动。 我怎样才能给背景一个不
我正在查看BTrees库并注意到有多个 TreeSet (和其他)类,例如 BTrees.IOBTree.TreeSet BTrees.OOBTree.TreeSet BTrees.LFBTree.T
我有一个小型 C++ 库,必须为 armeabi 和 armeabi7a 编译。我还有一个非常大的 c++ 库,只需要为 armeabi 编译。现在正在为两种架构编译它们(使用 NDK),但这使我的
我需要根据站点的当前部分稍微更改主题。 似乎 MuiThemeProvider 只在加载时设置 muiTheme;但需要在 props 变化时更新。 如何做到这一点? 最佳答案 您可以尝试将主题放在包
如何创建两个每个都有自己的计数器的 lSTListing 环境? 如果我使用例如 \lstnewenvironment{algorithm}[2]{ \renewcommand\lstlist
我想使用 Travis-CI 和 Github 基于分支设置部署。 IE。 - 如果我们从 develop 构建- 然后执行 /deploy.rb使用 DEV 环境主机名,如果 master - 然后
我有一个带有数据验证的 WPF MVVM 数据表单窗口。很多控件都是文本框。目前,数据绑定(bind)触发器设置为默认值,即。 e.失去焦点。这意味着仅在可能完全填写字段时才对其进行验证。所以当删除一
我有许多应用程序的内容页面,并最终为每个内容页面编写了很多 View 模型。例如。如果我有一个包含项目组的列表,我将有一个 ShowAllViewModel并绑定(bind)到内容页面和列表中单个项目
我有一个通用 View 和 4 个其他 View 。我在通用 View 中使用 Bootstrap 选项卡(导航选项卡)。我希望其他 4 个 View 成为通用 View 中 4 个选项卡的内容。由于
我希望针对 Maven 发布插件的不同目标有不同的配置选项。故事是这样的: 我正在将 Git 用于 SCM。我希望release:prepare插件在本地完成所有操作,并让release:perfor
我正在为一个项目使用AbstractTableModel制作一个自定义TableModel,并且我需要找到一种方法让复选框显示在某些行上,而不是其他行上。我已经实现了 getColumn 方法,但我希
摘自《Javascript 忍者的 secret 》一书: EVENTS ARE ASYNCHRONOUS Events, when they happen, can occur at unpredi
我正在尝试配置我的第一个 GWT 记录器,到目前为止,我已经将日志消息打印到我的 JS 控制台(FF 的 Firebug): 最终,我希望非SEVERE 消息转到consoleHa
我是一名优秀的程序员,十分优秀!